You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
/*@@ This file should be rewritten to use an arbitrary precision
@@ representation for "struct tree_int_cst" and "struct tree_real_cst".
return;
}
- if (count >= prec)
- count = (unsigned HOST_WIDE_INT) count & prec;
+#ifdef SHIFT_COUNT_TRUNCATED
+ if (SHIFT_COUNT_TRUNCATED)
+ count %= prec;
+#endif
if (count >= HOST_BITS_PER_WIDE_INT)
{
? -((unsigned HOST_WIDE_INT) h1 >> (HOST_BITS_PER_WIDE_INT - 1))
: 0);
- if (count >= prec)
- count = (unsigned HOST_WIDE_INT) count % prec;
+#ifdef SHIFT_COUNT_TRUNCATED
+ if (SHIFT_COUNT_TRUNCATED)
+ count %= prec;
+#endif
if (count >= HOST_BITS_PER_WIDE_INT)
{
got_it:
TREE_TYPE (t) = TREE_TYPE (arg1);
TREE_OVERFLOW (t)
- = ((notrunc ? !uns && overflow : force_fit_type (t, overflow))
+ = ((notrunc ? !uns && overflow : force_fit_type (t, overflow && !uns))
| TREE_OVERFLOW (arg1)
| TREE_OVERFLOW (arg2));
TREE_CONSTANT_OVERFLOW (t) = (TREE_OVERFLOW (t)
if (operand_equal_p (arg0, arg1, 0))
return 1;
- if (! INTEGRAL_TYPE_P (TREE_TYPE (arg0)))
+ if (! INTEGRAL_TYPE_P (TREE_TYPE (arg0))
+ || ! INTEGRAL_TYPE_P (TREE_TYPE (arg1)))
return 0;
/* Duplicate what shorten_compare does to ARG1 and see if that gives the
case SAVE_EXPR:
return build1 (TRUTH_NOT_EXPR, type, arg);
+
+ case CLEANUP_POINT_EXPR:
+ return build1 (CLEANUP_POINT_EXPR, type,
+ invert_truthvalue (TREE_OPERAND (arg, 0)));
}
if (TREE_CODE (TREE_TYPE (arg)) != BOOLEAN_TYPE)
abort ();
}
\f
/* Subroutine for fold_truthop: C is an INTEGER_CST interpreted as a P
- bit value. Arrange things so the extra bits will be set to zero if and]
+ bit value. Arrange things so the extra bits will be set to zero if and
only if C is signed-extended to its full width. */
static tree
c = convert (signed_type (type), c);
/* We work by getting just the sign bit into the low-order bit, then
- into the high-order bit, then sign-extened. We then XOR that value
+ into the high-order bit, then sign-extend. We then XOR that value
with C. */
temp = const_binop (RSHIFT_EXPR, c, size_int (p - 1), 0);
temp = const_binop (BIT_AND_EXPR, temp, size_int (1), 0);
}
else
{
+ tree testtype = TREE_TYPE (arg1);
test = arg1;
- true_value = integer_one_node;
- false_value = integer_zero_node;
+ true_value = convert (testtype, integer_one_node);
+ false_value = convert (testtype, integer_zero_node);
}
/* If ARG0 is complex we want to make sure we only evaluate
succeed in folding one part to a constant, we do not need
to make this SAVE_EXPR. Since we do this optimization
primarily to see if we do end up with constant and this
- SAVE_EXPR interfers with later optimizations, suppressing
+ SAVE_EXPR interferes with later optimizations, suppressing
it when we can is important. */
if (TREE_CODE (arg0) != SAVE_EXPR
}
else
{
+ tree testtype = TREE_TYPE (arg0);
test = arg0;
- true_value = integer_one_node;
- false_value = integer_zero_node;
+ true_value = convert (testtype, integer_one_node);
+ false_value = convert (testtype, integer_zero_node);
}
if (TREE_CODE (arg1) != SAVE_EXPR
and its values must be 0 or 1.
("true" is a fixed value perhaps depending on the language,
but we don't handle values other than 1 correctly yet.) */
- return invert_truthvalue (arg0);
+ tem = invert_truthvalue (arg0);
+ /* Avoid infinite recursion. */
+ if (TREE_CODE (tem) == TRUTH_NOT_EXPR)
+ return t;
+ return convert (type, tem);
case TRUTH_ANDIF_EXPR:
/* Note that the operands of this must be ints
case GE_EXPR:
case GT_EXPR:
return pedantic_non_lvalue
- (fold (build1 (ABS_EXPR, type, arg1)));
+ (convert (type, fold (build1 (ABS_EXPR,
+ TREE_TYPE (arg1), arg1))));
case LE_EXPR:
case LT_EXPR:
return pedantic_non_lvalue
(fold (build1 (NEGATE_EXPR, type,
- fold (build1 (ABS_EXPR, type, arg1)))));
+ convert (type,
+ fold (build1 (ABS_EXPR,
+ TREE_TYPE (arg1),
+ arg1))))));
}
/* If this is A != 0 ? A : 0, this is simply A. For ==, it is
appropriate. */
case CLEANUP_POINT_EXPR:
if (! TREE_SIDE_EFFECTS (arg0))
- return arg0;
+ return convert (type, arg0);
{
enum tree_code code0 = TREE_CODE (arg0);
tree arg00 = TREE_OPERAND (arg0, 0);
tree arg01;
- if (kind0 == '1')
+ if (kind0 == '1' || code0 == TRUTH_NOT_EXPR)
return fold (build1 (code0, type,
fold (build1 (CLEANUP_POINT_EXPR,
TREE_TYPE (arg00), arg00))));
- if ((kind0 == '<' || kind0 == '2')
- && ! TREE_SIDE_EFFECTS (arg01 = TREE_OPERAND (arg0, 1)))
- return fold (build (code0, type,
- fold (build1 (CLEANUP_POINT_EXPR,
- TREE_TYPE (arg00), arg00)),
- arg01));
+
+ if (kind0 == '<' || kind0 == '2'
+ || code0 == TRUTH_ANDIF_EXPR || code0 == TRUTH_ORIF_EXPR
+ || code0 == TRUTH_AND_EXPR || code0 == TRUTH_OR_EXPR
+ || code0 == TRUTH_XOR_EXPR)
+ {
+ arg01 = TREE_OPERAND (arg0, 1);
+
+ if (! TREE_SIDE_EFFECTS (arg00))
+ return fold (build (code0, type, arg00,
+ fold (build1 (CLEANUP_POINT_EXPR,
+ TREE_TYPE (arg01), arg01))));
+
+ if (! TREE_SIDE_EFFECTS (arg01))
+ return fold (build (code0, type,
+ fold (build1 (CLEANUP_POINT_EXPR,
+ TREE_TYPE (arg00), arg00)),
+ arg01));
+ }
return t;
}