summaryrefslogtreecommitdiffhomepage
path: root/ir/tv
diff options
context:
space:
mode:
authorAndreas Zwinkau <zwinkau@kit.edu>2015-05-18 17:00:14 +0200
committerAndreas Zwinkau <zwinkau@kit.edu>2015-05-18 17:07:56 +0200
commit09950fc0563371e50eff9e6b45a21c0015752dfc (patch)
treeb1c292444097bb99a325e2303eea2c0f72192b7b /ir/tv
parente0629c8128006573bba94517256b9d5707a5a7f5 (diff)
Fix fc_cast
Matze's cleanup broke things 8ebe31d226843d6f2cdfcc1ee100ca607c79ba65 Apparently, value==result shall be explicitly allowed, but in the case of NaN, result was modified and afterwards a read from value returns the wrong results. Fix was to move the reads before the writes. Also, a cast from implicit one to explicit one forgot to set the one. Likewise, the size comparison was oblivious of explicit ones. Adds few more asserts. Adds a unittest to check NaN payload stuff.
Diffstat (limited to 'ir/tv')
-rw-r--r--ir/tv/fltcalc.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/ir/tv/fltcalc.c b/ir/tv/fltcalc.c
index 2959d7d..c190fa5 100644
--- a/ir/tv/fltcalc.c
+++ b/ir/tv/fltcalc.c
@@ -722,20 +722,26 @@ void fc_cast(const fp_value *value, const float_descriptor_t *dest,
memcpy(result, value, fp_value_size);
return;
}
+ /* Possible: value == result */
switch ((value_class_t)value->clss) {
case FC_NAN: {
+ unsigned const src_mant = value->desc.mantissa_size - value->desc.explicit_one;
+ unsigned const dst_mant = dest->mantissa_size - dest->explicit_one;
+ assert (!fc_zero_mantissa(value));
result->desc = *dest;
result->clss = FC_NAN;
result->sign = value->sign;
sc_max_from_bits(dest->exponent_size, 0, _exp(result));
- unsigned const src_mant = value->desc.mantissa_size;
- unsigned const dst_mant = dest->mantissa_size;
if (dst_mant < src_mant) {
sc_shrI(_mant(value), src_mant - dst_mant, _mant(result));
} else {
sc_shlI(_mant(value), dst_mant - src_mant, _mant(result));
}
+ if (dest->explicit_one)
+ sc_set_bit_at(_mant(result), dest->mantissa_size + ROUNDING_BITS - 1);
+ assert (fc_nan_is_quiet(value) == fc_nan_is_quiet(result));
+ assert (fc_is_nan(result));
return;
}