summaryrefslogtreecommitdiffhomepage
path: root/ir/tv
diff options
context:
space:
mode:
authorChristoph Mallon <christoph.mallon@gmx.de>2016-02-25 19:44:26 +0100
committerChristoph Mallon <christoph.mallon@gmx.de>2016-02-26 06:49:04 +0100
commit6d4b532920ddc4188d9181df229565c8618d110e (patch)
tree623397b897927989d219f3c52d07287a074ca185 /ir/tv
parentfa7eb6eee26542375a5cc5a02fd7ab060cb86389 (diff)
tv: Add get_tarval_magnitude().
Diffstat (limited to 'ir/tv')
-rw-r--r--ir/tv/tv.c17
-rw-r--r--ir/tv/tv_t.h5
2 files changed, 22 insertions, 0 deletions
diff --git a/ir/tv/tv.c b/ir/tv/tv.c
index 3e21aa8..3dd2183 100644
--- a/ir/tv/tv.c
+++ b/ir/tv/tv.c
@@ -1229,6 +1229,23 @@ int get_tarval_highest_bit(ir_tarval const *tv)
return -1;
}
+unsigned get_tarval_magnitude(ir_tarval const *tv)
+{
+ assert(get_mode_arithmetic(tv->mode) == irma_twos_complement);
+ unsigned const size = get_mode_size_bits(tv->mode);
+ unsigned const neg = tarval_get_bit(tv, size - 1);
+ unsigned const ext = neg ? (1U << SC_BITS) - 1 : 0;
+
+ unsigned l = get_mode_size_bytes(tv->mode);
+ for (unsigned i = l; i-- != 0;) {
+ unsigned char const v = get_tarval_sub_bits(tv, i);
+ if (v != ext)
+ return i * SC_BITS + (32 - nlz(v ^ ext)) + 1;
+ }
+
+ return 1;
+}
+
int tarval_zero_mantissa(ir_tarval const *tv)
{
assert(get_mode_arithmetic(tv->mode) == irma_ieee754
diff --git a/ir/tv/tv_t.h b/ir/tv/tv_t.h
index e8d6ac4..f525a4d 100644
--- a/ir/tv/tv_t.h
+++ b/ir/tv/tv_t.h
@@ -136,6 +136,11 @@ ir_tarval *get_tarval_small(ir_mode *mode);
ir_tarval *get_tarval_epsilon(ir_mode *mode);
/**
+ * Get the number of bits required to reconstruct this tarval by sign extension.
+ */
+unsigned get_tarval_magnitude(ir_tarval const *tv);
+
+/**
* Get the @p idx'th bit of the internal representation of the given tarval
* @p tv.
*/