From 506678c708290e6962afaed113f4c98929f15baa Mon Sep 17 00:00:00 2001 From: Michael Beck Date: Wed, 3 Feb 2010 22:15:45 +0000 Subject: [PATCH] Add get_tarval_lowest_bit() and get_tarval_popcnt(), expand some documentation. [r27036] --- include/libfirm/tv.h | 24 ++++++++++++++++++++--- ir/tv/tv.c | 45 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/include/libfirm/tv.h b/include/libfirm/tv.h index 6433d7e91..5b3cdda14 100644 --- a/include/libfirm/tv.h +++ b/include/libfirm/tv.h @@ -716,10 +716,10 @@ char *get_tarval_bitpattern(tarval *tv); * * To query a 32bit value the following code can be used: * - * val0 = tarval_sub_bits(tv, 0); + * val0 = tarval_sub_bits(tv, 0); <- lowest bits * val1 = tarval_sub_bits(tv, 1); * val2 = tarval_sub_bits(tv, 2); - * val3 = tarval_sub_bits(tv, 3); + * val3 = tarval_sub_bits(tv, 3); <- highest bits * * Because this is the bit representation of the target machine, only the following * operations are legal on the result: @@ -728,7 +728,7 @@ char *get_tarval_bitpattern(tarval *tv); * - bitwise logical operations to select/mask bits * * @param tv the tarval - * @param byte_ofs the byte offset + * @param byte_ofs the byte offset from lower to higher * * @note * The result of this function is undefined if the mode is neither integer nor float. @@ -743,6 +743,24 @@ unsigned char get_tarval_sub_bits(tarval *tv, unsigned byte_ofs); */ int tarval_is_single_bit(tarval *tv); +/** + * Return the number of set bits in a given (integer) tarval. + * + * @param tv the tarval + * + * @return number of set bits or -1 on error + */ +int get_tarval_popcnt(tarval *tv); + +/** + * Return the number of the lowest set bit in a given (integer) tarval. + * + * @param tv the tarval + * + * @return number of lowest set bit or -1 on error + */ +int get_tarval_lowest_bit(tarval *tv); + /** * Output a tarval to a string buffer. * diff --git a/ir/tv/tv.c b/ir/tv/tv.c index 30b400043..1c2ca0f11 100644 --- a/ir/tv/tv.c +++ b/ir/tv/tv.c @@ -41,6 +41,7 @@ #endif #include +#include "bitfiddle.h" #include "tv_t.h" #include "set.h" #include "entity_t.h" @@ -1624,6 +1625,50 @@ int tarval_is_single_bit(tarval *tv) { return bits; } +/* + * Return the number of set bits in a given (integer) tarval. + */ +int get_tarval_popcnt(tarval *tv) +{ + int i, l; + int bits; + + if (!tv || tv == tarval_bad) return -1; + if (! mode_is_int(tv->mode)) return -1; + + l = get_mode_size_bytes(tv->mode); + for (bits = 0, i = l - 1; i >= 0; --i) { + unsigned char v = get_tarval_sub_bits(tv, (unsigned)i); + + bits += popcnt(v); + } + return bits; +} + +/** + * Return the number of the lowest set bit in a given (integer) tarval. + * + * @param tv the tarval + * + * @return number of lowest set bit or -1 on error + */ +int get_tarval_lowest_bit(tarval *tv) +{ + int i, l; + + if (!tv || tv == tarval_bad) return -1; + if (! mode_is_int(tv->mode)) return -1; + + l = get_mode_size_bytes(tv->mode); + for (i = 0; i < l; ++i) { + unsigned char v = get_tarval_sub_bits(tv, (unsigned)i); + + if (v) + return ntz(v) + i * 8; + } + return -1; +} + /* * Returns non-zero if the mantissa of a floating point IEEE-754 * tarval is zero (i.e. 1.0Exxx) -- 2.20.1