(integer_pow2): Mask value to width of type.

(tree_log2): New function.

From-SVN: r13374
This commit is contained in:
Richard Kenner 1997-01-04 22:15:48 -05:00
parent 86b5812c18
commit 5cb1f2fa91

View File

@ -1,5 +1,5 @@
/* Language-independent node constructors for parse phase of GNU compiler.
Copyright (C) 1987, 88, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
Copyright (C) 1987, 88, 92-96, 1997 Free Software Foundation, Inc.
This file is part of GNU CC.
@ -1625,6 +1625,7 @@ int
integer_pow2p (expr)
tree expr;
{
int prec;
HOST_WIDE_INT high, low;
STRIP_NOPS (expr);
@ -1637,9 +1638,25 @@ integer_pow2p (expr)
if (TREE_CODE (expr) != INTEGER_CST || TREE_CONSTANT_OVERFLOW (expr))
return 0;
prec = (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE
? POINTER_SIZE : TYPE_PRECISION (TREE_TYPE (expr)));
high = TREE_INT_CST_HIGH (expr);
low = TREE_INT_CST_LOW (expr);
/* First clear all bits that are beyond the type's precision in case
we've been sign extended. */
if (prec == 2 * HOST_BITS_PER_WIDE_INT)
;
else if (prec > HOST_BITS_PER_WIDE_INT)
high &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT));
else
{
high = 0;
if (prec < HOST_BITS_PER_WIDE_INT)
low &= ~((HOST_WIDE_INT) (-1) << prec);
}
if (high == 0 && low == 0)
return 0;
@ -1647,6 +1664,45 @@ integer_pow2p (expr)
|| (low == 0 && (high & (high - 1)) == 0));
}
/* Return the power of two represented by a tree node known to be a
power of two. */
int
tree_log2 (expr)
tree expr;
{
int prec;
HOST_WIDE_INT high, low;
STRIP_NOPS (expr);
if (TREE_CODE (expr) == COMPLEX_CST)
return tree_log2 (TREE_REALPART (expr));
prec = (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE
? POINTER_SIZE : TYPE_PRECISION (TREE_TYPE (expr)));
high = TREE_INT_CST_HIGH (expr);
low = TREE_INT_CST_LOW (expr);
/* First clear all bits that are beyond the type's precision in case
we've been sign extended. */
if (prec == 2 * HOST_BITS_PER_WIDE_INT)
;
else if (prec > HOST_BITS_PER_WIDE_INT)
high &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT));
else
{
high = 0;
if (prec < HOST_BITS_PER_WIDE_INT)
low &= ~((HOST_WIDE_INT) (-1) << prec);
}
return (high != 0 ? HOST_BITS_PER_WIDE_INT + exact_log2 (high)
: exact_log2 (low));
}
/* Return 1 if EXPR is the real constant zero. */
int