aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-common.c
diff options
context:
space:
mode:
authorJason Merrill <merrill@gnu.org>1994-09-02 23:40:51 +0000
committerJason Merrill <merrill@gnu.org>1994-09-02 23:40:51 +0000
commit6acfe908e3d037bc48d46e72aa02f2949011caee (patch)
tree51a80e6d7f5d01930d2f10061a4ec67d58d424e8 /gcc/c-common.c
parent8294accf6dc5c51c9112478f5025faa2b8b5931a (diff)
downloadgcc-6acfe908e3d037bc48d46e72aa02f2949011caee.zip
gcc-6acfe908e3d037bc48d46e72aa02f2949011caee.tar.gz
gcc-6acfe908e3d037bc48d46e72aa02f2949011caee.tar.bz2
(min_precision): Move from c-decl.c
From-SVN: r8020
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r--gcc/c-common.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 0d9184f..a0b7fd3 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -1346,6 +1346,37 @@ type_for_mode (mode, unsignedp)
return 0;
}
+/* Return the minimum number of bits needed to represent VALUE in a
+ signed or unsigned type, UNSIGNEDP says which. */
+
+int
+min_precision (value, unsignedp)
+ tree value;
+ int unsignedp;
+{
+ int log;
+
+ /* If the value is negative, compute its negative minus 1. The latter
+ adjustment is because the absolute value of the largest negative value
+ is one larger than the largest positive value. This is equivalent to
+ a bit-wise negation, so use that operation instead. */
+
+ if (tree_int_cst_sgn (value) < 0)
+ value = fold (build1 (BIT_NOT_EXPR, TREE_TYPE (value), value));
+
+ /* Return the number of bits needed, taking into account the fact
+ that we need one more bit for a signed than unsigned type. */
+
+ if (integer_zerop (value))
+ log = 0;
+ else if (TREE_INT_CST_HIGH (value) != 0)
+ log = HOST_BITS_PER_WIDE_INT + floor_log2 (TREE_INT_CST_HIGH (value));
+ else
+ log = floor_log2 (TREE_INT_CST_LOW (value));
+
+ return log + 1 + ! unsignedp;
+}
+
/* Print an error message for invalid operands to arith operation CODE.
NOP_EXPR is used as a special case (see truthvalue_conversion). */