This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Sign-extend CONST_INTs within their modes
- To: Geoff Keating <geoffk at redhat dot com>
- Subject: Re: Sign-extend CONST_INTs within their modes
- From: Alexandre Oliva <aoliva at redhat dot com>
- Date: 04 Apr 2001 12:22:24 -0300
- Cc: gcc-patches at gcc dot gnu dot org, bob dot koninckx at mech dot kuleuven dot ac dot be
- Organization: GCC Team, Red Hat
- References: <org0gb1tmu.fsf@guarana.lsd.ic.unicamp.br><jmbsqzv7bi.fsf@geoffk.org> <or4rwb5pi2.fsf@guarana.lsd.ic.unicamp.br><200104022312.QAA09069@geoffk.org>
On Apr 2, 2001, Geoff Keating <geoffk@geoffk.org> wrote:
> This is OK, please commit it.
It turned out that my pre-commit bootstrap detected a few problems on
x86. Dunno if it's from new code that wasn't present in the 3.0
branch, in which I had originally tested the patch because of
brokenness in mainline, or if I still had the *_operand checking
disabled (I may have moved it from RTL to MISC checks only after
running the bootstrap, in which case you may have gone undetected).
The changes needed for i386 to bootstrap are below. Ok to check them
in along with the rest of the patch?
I've also had to turn the `abort()'s in the new misc-checking tests in
the recog predicates to `return 0'. Having the *_operand() functions
abort() would fail in a number of attempts to recognize insns, usually
involving compares, generated by various optimization passes.
Something like:
(compare:<M1> (const_int <I>) (reg:<M2> ...))
would abort() if the recognizer tested the first operand of the
compare with a mode narrower than that of M2. This actually happens
with the recognizers generated for x86 and, apparently, for sparc,
that failed similarly when the tests were enabled.
Also, since the predicates no longer abort(), the change to combine.c
is no longer needed, so I pulled it out. The abort()s were useful to
find a number of errors in codegen, but they apparently can't be used
in practice. Which is probably not such a bad thing: if the insn
survives long enough, recog will eventually fail to match the insn to
existing patterns and will abort(). But we won't be detecting lack of
sign-extension of CONST_INTs are early as possible, and other
optimization passes may end up hiding the errors. Suggestions?
Here are the revised patches, bootstrapped yesterday on alpha, sparc
and x86, built alpha-x-ppc (except for David's patch, that I didn't
have when I started testing). I didn't re-run tests on pa, because my
local pa box is very slow, but there haven't been any significant
changes that might affect it, and I'm pretty sure I did test it after
moving the tests from RTL to MISC checking.
Ok to install the revised patch?
Index: gcc/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* recog.c (general_operand, immediate_operand,
nonmemory_operand): Require CONST_INTs to be sign-extended
values for their modes.
* 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.
Index: gcc/recog.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/recog.c,v
retrieving revision 1.95
diff -u -p -r1.95 recog.c
--- gcc/recog.c 2001/04/04 05:03:29 1.95
+++ gcc/recog.c 2001/04/04 15:07:16
@@ -1108,6 +1108,12 @@ general_operand (op, mode)
&& GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
return 0;
+#ifdef ENABLE_CHECKING
+ if (GET_CODE (op) == CONST_INT
+ && trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
+ return 0;
+#endif
+
if (CONSTANT_P (op))
return ((GET_MODE (op) == VOIDmode || GET_MODE (op) == mode
|| mode == VOIDmode)
@@ -1284,6 +1290,12 @@ immediate_operand (op, mode)
&& GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
return 0;
+#ifdef ENABLE_CHECKING
+ if (GET_CODE (op) == CONST_INT
+ && trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
+ return 0;
+#endif
+
/* Accept CONSTANT_P_RTX, since it will be gone by CSE1 and
result in 0/1. It seems a safe assumption that this is
in range for everyone. */
@@ -1354,6 +1366,12 @@ nonmemory_operand (op, mode)
&& GET_MODE_CLASS (mode) != MODE_INT
&& GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
return 0;
+
+#ifdef ENABLE_CHECKING
+ if (GET_CODE (op) == CONST_INT
+ && trunc_int_for_mode (INTVAL (op), mode) != INTVAL (op))
+ return 0;
+#endif
return ((GET_MODE (op) == VOIDmode || GET_MODE (op) == mode
|| mode == VOIDmode)
Index: gcc/expmed.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/expmed.c,v
retrieving revision 1.77
diff -u -p -r1.77 expmed.c
--- gcc/expmed.c 2001/03/22 18:48:28 1.77
+++ gcc/expmed.c 2001/03/30 07:58:16
@@ -587,6 +587,8 @@ store_bit_field (str_rtx, bitsize, bitnu
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
@@ -2780,7 +2782,7 @@ expand_mult_highpart (mode, op0, cnst1,
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;
@@ -3267,7 +3269,7 @@ expand_divmod (rem_flag, code, mode, op0
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)
@@ -3297,7 +3299,8 @@ expand_divmod (rem_flag, code, mode, op0
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),
@@ -3334,7 +3337,10 @@ expand_divmod (rem_flag, code, mode, op0
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);
@@ -3833,8 +3839,10 @@ expand_divmod (rem_flag, code, mode, op0
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,
Index: gcc/expr.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/expr.c,v
retrieving revision 1.307
diff -u -p -r1.307 expr.c
--- gcc/expr.c 2001/03/28 11:03:51 1.307
+++ gcc/expr.c 2001/03/30 07:58:18
@@ -1360,7 +1360,7 @@ convert_modes (mode, oldmode, x, unsigne
&& (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, mo
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;
Index: gcc/integrate.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/integrate.c,v
retrieving revision 1.137
diff -u -p -r1.137 integrate.c
--- gcc/integrate.c 2001/03/28 11:03:54 1.137
+++ gcc/integrate.c 2001/03/30 07:58:19
@@ -702,13 +702,24 @@ expand_inline_function (fndecl, parms, t
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);
}
Index: gcc/optabs.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/optabs.c,v
retrieving revision 1.91
diff -u -p -r1.91 optabs.c
--- gcc/optabs.c 2001/03/28 11:03:56 1.91
+++ gcc/optabs.c 2001/03/30 07:58:19
@@ -723,17 +723,25 @@ expand_binop (mode, binoptab, op0, op1,
}
/* 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)
Index: gcc/stmt.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/stmt.c,v
retrieving revision 1.190
diff -u -p -r1.190 stmt.c
--- gcc/stmt.c 2001/03/28 11:03:58 1.190
+++ gcc/stmt.c 2001/03/30 08:12:44
@@ -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_la
/* 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_la
/* 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_la
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_la
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_la
/* 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_la
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_la
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_la
{
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_la
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_la
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_la
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_la
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_la
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_la
/* 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_la
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_la
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);
}
Index: gcc/unroll.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/unroll.c,v
retrieving revision 1.125
diff -u -p -r1.125 unroll.c
--- gcc/unroll.c 2001/01/25 09:28:55 1.125
+++ gcc/unroll.c 2001/03/30 07:58:21
@@ -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
Index: gcc/varasm.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/varasm.c,v
retrieving revision 1.170
diff -u -p -r1.170 varasm.c
--- gcc/varasm.c 2001/03/23 22:00:40 1.170
+++ gcc/varasm.c 2001/03/30 07:58:22
@@ -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);
Index: gcc/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* config/rs6000/rs6000.c (logical_operand): CONST_INTs are
already sign-extended.
(rs6000_emit_prologue): Make register iterator signed.
(rs6000_emit_epilogue): Likewise.
* config/rs6000/rs6000.md (addsi3, adddi3): Sign-extend high
and low.
(movsf split, movdf split): Sign-extend CONST_INTs.
(movdi splits): Likewise.
Index: gcc/config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.172
diff -u -p -r1.172 rs6000.c
--- gcc/config/rs6000/rs6000.c 2001/03/28 11:19:20 1.172
+++ gcc/config/rs6000/rs6000.c 2001/03/30 13:39:15
@@ -965,7 +965,7 @@ add_operand (op, mode)
{
return (reg_or_short_operand (op, mode)
|| (GET_CODE (op) == CONST_INT
- && CONST_OK_FOR_LETTER_P (INTVAL(op), 'L')));
+ && CONST_OK_FOR_LETTER_P (INTVAL (op), 'L')));
}
/* Return 1 if OP is a constant but not a valid add_operand. */
@@ -977,7 +977,7 @@ non_add_cint_operand (op, mode)
{
return (GET_CODE (op) == CONST_INT
&& (unsigned HOST_WIDE_INT) (INTVAL (op) + 0x8000) >= 0x10000
- && ! CONST_OK_FOR_LETTER_P (INTVAL(op), 'L'));
+ && ! CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
}
/* Return 1 if the operand is a non-special register or a constant that
@@ -995,13 +995,7 @@ logical_operand (op, mode)
return 1;
if (GET_CODE (op) == CONST_INT)
- {
- opl = INTVAL (op) & GET_MODE_MASK (mode);
- if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
- oph = 0;
- else
- oph = INTVAL (op) >> (HOST_BITS_PER_WIDE_INT - 1);
- }
+ opl = INTVAL (op);
else if (GET_CODE (op) == CONST_DOUBLE)
{
if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
@@ -1009,13 +1003,21 @@ logical_operand (op, mode)
opl = CONST_DOUBLE_LOW (op);
oph = CONST_DOUBLE_HIGH (op);
+
+ if (oph != ((unsigned HOST_WIDE_INT)0
+ - ((opl & ((unsigned HOST_WIDE_INT)1
+ << (HOST_BITS_PER_WIDE_INT - 1))) != 0)))
+ return 0;
}
else
return 0;
+
+ /* This must really be SImode, not MODE. */
+ if (opl != trunc_int_for_mode (opl, SImode))
+ return 0;
- return (oph == 0
- && ((opl & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0
- || (opl & ~ (unsigned HOST_WIDE_INT) 0xffff0000) == 0));
+ return ((opl & 0xffff) == 0
+ || (opl & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0);
}
/* Return 1 if C is a constant that is not a logical operand (as
@@ -5762,7 +5762,7 @@ rs6000_emit_prologue ()
easiest way to get the frame unwind information emitted. */
if (current_function_calls_eh_return)
{
- unsigned int i, regno;
+ int i, regno;
for (i = 0; ; ++i)
{
rtx addr, reg, mem;
@@ -6006,7 +6006,7 @@ rs6000_emit_epilogue (sibcall)
/* Load exception handler data registers, if needed. */
if (current_function_calls_eh_return)
{
- unsigned int i, regno;
+ int i, regno;
for (i = 0; ; ++i)
{
rtx addr, mem;
Index: gcc/config/rs6000/rs6000.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.111
diff -u -p -r1.111 rs6000.md
--- gcc/config/rs6000/rs6000.md 2001/03/28 12:22:48 1.111
+++ gcc/config/rs6000/rs6000.md 2001/03/30 13:39:19
@@ -1426,7 +1426,10 @@
HOST_WIDE_INT high = INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff);
if (low & 0x8000)
- high += 0x10000, low |= ((HOST_WIDE_INT) -1) << 16;
+ {
+ high = trunc_int_for_mode (high + 0x10000, SImode);
+ low = trunc_int_for_mode (low, HImode);
+ }
/* The ordering here is important for the prolog expander.
When space is allocated from the stack, adding 'low' first may
@@ -1529,7 +1532,10 @@
HOST_WIDE_INT high = INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff);
if (low & 0x8000)
- high += 0x10000, low |= ((HOST_WIDE_INT) -1) << 16;
+ {
+ high = trunc_int_for_mode (high + 0x10000, SImode);
+ low = trunc_int_for_mode (low, HImode);
+ }
operands[3] = GEN_INT (high);
operands[4] = GEN_INT (low);
@@ -5759,7 +5765,10 @@
HOST_WIDE_INT high = INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff);
if (low & 0x8000)
- high += 0x10000, low |= ((HOST_WIDE_INT) -1) << 16;
+ {
+ high = trunc_int_for_mode (high + 0x10000, SImode);
+ low = trunc_int_for_mode (low, HImode);
+ }
emit_insn (gen_adddi3 (tmp, operands[1], GEN_INT (high)));
emit_insn (gen_adddi3 (operands[0], tmp, GEN_INT (low)));
@@ -5858,7 +5867,10 @@
HOST_WIDE_INT high = INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff);
if (low & 0x8000)
- high+=0x10000, low |= ((HOST_WIDE_INT) -1) << 16;
+ {
+ high = trunc_int_for_mode (high + 0x10000, SImode);
+ low = trunc_int_for_mode (low, HImode);
+ }
operands[3] = GEN_INT (high);
operands[4] = GEN_INT (low);
@@ -7573,7 +7585,7 @@
else
operands[2] = gen_lowpart (SImode, operands[0]);
- operands[3] = GEN_INT(l);
+ operands[3] = GEN_INT (trunc_int_for_mode (l, SImode));
}")
(define_insn "*movsf_hardfloat"
@@ -7663,8 +7675,8 @@
operands[2] = operand_subword (operands[0], endian, 0, DFmode);
operands[3] = operand_subword (operands[0], 1 - endian, 0, DFmode);
- operands[4] = GEN_INT (l[endian]);
- operands[5] = GEN_INT (l[1 - endian]);
+ operands[4] = GEN_INT (trunc_int_for_mode (l[endian], SImode));
+ operands[5] = GEN_INT (trunc_int_for_mode (l[1 - endian], SImode));
}")
(define_split
@@ -8009,7 +8021,7 @@
(match_dup 3)))]
"
{
- operands[2] = GEN_INT (INTVAL (operands[1]) & 0xffff0000);
+ operands[2] = GEN_INT (INTVAL (operands[1]) & (~ (HOST_WIDE_INT) 0xffff));
operands[3] = GEN_INT (INTVAL (operands[1]) & 0xffff);
}")
@@ -8029,7 +8041,7 @@
(match_dup 3)))]
"
{
- operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[1]) & 0xffff0000);
+ operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[1]) & (~ (HOST_WIDE_INT) 0xffff));
operands[3] = GEN_INT (CONST_DOUBLE_LOW (operands[1]) & 0xffff);
}")
@@ -8050,7 +8062,7 @@
(match_dup 3)))]
"
{
- operands[2] = GEN_INT (INTVAL (operands[1]) & 0xffff0000);
+ operands[2] = GEN_INT (INTVAL (operands[1]) & (~ (HOST_WIDE_INT) 0xffff));
operands[3] = GEN_INT (INTVAL (operands[1]) & 0xffff);
}")
Index: gcc/ChangeLog
from David Edelsohn <dje@watson.ibm.com>
* config/rs6000/rs6000.c (rs6000_emit_move): Adjust for 64-bit
HOST_WIDE_INT.
Index: gcc/config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.166
diff -c -p -r1.166 rs6000.c
*************** rs6000_emit_move (dest, source, mode)
*** 1688,1698 ****
}
else if (mode == Pmode
&& CONSTANT_P (operands[1])
! && (((HOST_BITS_PER_WIDE_INT != 32
! || GET_CODE (operands[1]) != CONST_INT)
! && ! easy_fp_constant (operands[1], mode))
! || (GET_CODE (operands[0]) == REG
! && FP_REGNO_P (REGNO (operands[0]))))
&& GET_CODE (operands[1]) != HIGH
&& ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1])
&& ! TOC_RELATIVE_EXPR_P (operands[1]))
--- 1688,1699 ----
}
else if (mode == Pmode
&& CONSTANT_P (operands[1])
! && ((GET_CODE (operands[1]) != CONST_INT
! && ! easy_fp_constant (operands[1], mode))
! || (GET_CODE (operands[1]) == CONST_INT
! && num_insns_constant (operands[1], mode) > 2)
! || (GET_CODE (operands[0]) == REG
! && FP_REGNO_P (REGNO (operands[0]))))
&& GET_CODE (operands[1]) != HIGH
&& ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1])
&& ! TOC_RELATIVE_EXPR_P (operands[1]))
Index: gcc/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* config/i386/i386.md: Apply trunc_int_for_mode() to GEN_INT
operands that make it to RTL.
Index: gcc/config/i386/i386.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.md,v
retrieving revision 1.253
diff -u -p -r1.253 i386.md
--- gcc/config/i386/i386.md 2001/04/01 09:50:06 1.253
+++ gcc/config/i386/i386.md 2001/04/04 14:56:20
@@ -7929,7 +7929,8 @@
mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
- operands[3] = gen_rtx_AND (mode, operands[0], GEN_INT (mask));
+ operands[3] = gen_rtx_AND (mode, operands[0],
+ GEN_INT (trunc_int_for_mode (mask, mode)));
}")
;; %%% This used to optimize known byte-wide and operations to memory,
@@ -9150,7 +9151,7 @@
"TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
[(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
(clobber (reg:CC 17))])]
- "operands[1] = GEN_INT (0x80000000);
+ "operands[1] = GEN_INT (trunc_int_for_mode (0x80000000, SImode));
operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
(define_split
@@ -9169,7 +9170,7 @@
size = 10;
operands[0] = gen_rtx_MEM (QImode, XEXP (operands[0], 0));
operands[0] = adj_offsettable_operand (operands[0], size - 1);
- operands[1] = GEN_INT (0x80);
+ operands[1] = GEN_INT (trunc_int_for_mode (0x80, QImode));
}")
(define_expand "negdf2"
@@ -9205,7 +9206,7 @@
"TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
[(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
(clobber (reg:CC 17))])]
- "operands[4] = GEN_INT (0x80000000);
+ "operands[4] = GEN_INT (trunc_int_for_mode (0x80000000, SImode));
split_di (operands+0, 1, operands+2, operands+3);")
(define_expand "negxf2"
@@ -9466,7 +9467,7 @@
"TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
[(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
(clobber (reg:CC 17))])]
- "operands[1] = GEN_INT (~0x80000000);
+ "operands[1] = GEN_INT (trunc_int_for_mode (~0x80000000, SImode));
operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
(define_split
@@ -9485,7 +9486,7 @@
size = 10;
operands[0] = gen_rtx_MEM (QImode, XEXP (operands[0], 0));
operands[0] = adj_offsettable_operand (operands[0], size - 1);
- operands[1] = GEN_INT (~0x80);
+ operands[1] = GEN_INT (trunc_int_for_mode (~0x80, QImode));
}")
(define_expand "absdf2"
@@ -9588,7 +9589,7 @@
"TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
[(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
(clobber (reg:CC 17))])]
- "operands[4] = GEN_INT (~0x80000000);
+ "operands[4] = GEN_INT (trunc_int_for_mode (~0x80000000, SImode));
split_di (operands+0, 1, operands+2, operands+3);")
(define_expand "absxf2"
@@ -9632,7 +9633,7 @@
"TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
[(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
(clobber (reg:CC 17))])]
- "operands[1] = GEN_INT (~0x8000);
+ "operands[1] = GEN_INT (trunc_int_for_mode (~0x8000, SImode));
operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
(define_insn "*abstf2_if"
@@ -9658,7 +9659,7 @@
"TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
[(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
(clobber (reg:CC 17))])]
- "operands[1] = GEN_INT (~0x8000);
+ "operands[1] = GEN_INT (trunc_int_for_mode (~0x8000, SImode));
operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
(define_insn "*abssf2_1"
@@ -10040,7 +10041,8 @@
[(set (match_dup 0)
(mult:DI (match_dup 1)
(match_dup 2)))]
- "operands[2] = GEN_INT (1 << INTVAL (operands[2]));")
+ "operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
+ DImode));")
;; This pattern can't accept a variable shift count, since shifts by
;; zero don't affect the flags. We assume that shifts by constant
@@ -10251,7 +10253,8 @@
rtx pat;
operands[0] = gen_lowpart (SImode, operands[0]);
operands[1] = gen_lowpart (Pmode, operands[1]);
- operands[2] = GEN_INT (1 << INTVAL (operands[2]));
+ operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
+ Pmode));
pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
if (Pmode != SImode)
pat = gen_rtx_SUBREG (SImode, pat, 0);
@@ -10311,7 +10314,8 @@
"
{
operands[1] = gen_lowpart (Pmode, operands[1]);
- operands[2] = GEN_INT (1 << INTVAL (operands[2]));
+ operands[2] = GEN_INT (trunc_int_for_mode (1 << INTVAL (operands[2]),
+ Pmode));
}")
;; This pattern can't accept a variable shift count, since shifts by
@@ -15894,7 +15898,9 @@
(set (match_dup 0)
(and:SI (match_dup 1) (match_dup 2)))])]
"operands[2]
- = GEN_INT (INTVAL (operands[2]) & GET_MODE_MASK (GET_MODE (operands[0])));
+ = GEN_INT (trunc_int_for_mode (INTVAL (operands[2])
+ & GET_MODE_MASK (GET_MODE (operands[0])),
+ SImode));
operands[0] = gen_lowpart (SImode, operands[0]);
operands[1] = gen_lowpart (SImode, operands[1]);")
@@ -15912,7 +15918,9 @@
(compare:CCNO (and:SI (match_dup 0) (match_dup 1))
(const_int 0)))]
"operands[1]
- = GEN_INT (INTVAL (operands[1]) & GET_MODE_MASK (GET_MODE (operands[0])));
+ = GEN_INT (trunc_int_for_mode (INTVAL (operands[1])
+ & GET_MODE_MASK (GET_MODE (operands[0])),
+ SImode));
operands[0] = gen_lowpart (SImode, operands[0]);")
(define_split
--
Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist *Please* write to mailing lists, not to me