summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2013-11-04 16:54:15 +0000
committerScott Wood <scottwood@freescale.com>2014-01-07 18:36:24 -0600
commitd06b3326dfd02f3f036b670d622fe56eb68a5f30 (patch)
tree7af31abd819a314106ebc88614a7b0d315b7d87f
parent4f6db5efff8256c7f608285877e892e7e649137a (diff)
downloadlinux-d06b3326dfd02f3f036b670d622fe56eb68a5f30.tar.gz
linux-d06b3326dfd02f3f036b670d622fe56eb68a5f30.tar.bz2
linux-d06b3326dfd02f3f036b670d622fe56eb68a5f30.zip
math-emu: fix floating-point to integer overflow detection
On overflow, the math-emu macro _FP_TO_INT_ROUND tries to saturate its result (subject to the value of rsigned specifying the desired overflow semantics). However, if the rounding step has the effect of increasing the exponent so as to cause overflow (if the rounded result is 1 larger than the largest positive value with the given number of bits, allowing for signedness), the overflow does not get detected, meaning that for unsigned results 0 is produced instead of the maximum unsigned integer with the give number of bits, without an exception being raised for overflow, and that for signed results the minimum (negative) value is produced instead of the maximum (positive) value, again without an exception. This patch makes the code check for rounding increasing the exponent and adjusts the exponent value as needed for the overflow check. Signed-off-by: Joseph Myers <joseph@codesourcery.com> Signed-off-by: Scott Wood <scottwood@freescale.com>
-rw-r--r--include/math-emu/op-common.h5
1 files changed, 5 insertions, 0 deletions
diff --git a/include/math-emu/op-common.h b/include/math-emu/op-common.h
index 70fe5e989ace..6bdf8c61d221 100644
--- a/include/math-emu/op-common.h
+++ b/include/math-emu/op-common.h
@@ -743,12 +743,17 @@ do { \
} \
else \
{ \
+ int _lz0, _lz1; \
if (X##_e <= -_FP_WORKBITS - 1) \
_FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \
else \
_FP_FRAC_SRS_##wc(X, _FP_FRACBITS_##fs - 1 - X##_e, \
_FP_WFRACBITS_##fs); \
+ _FP_FRAC_CLZ_##wc(_lz0, X); \
_FP_ROUND(wc, X); \
+ _FP_FRAC_CLZ_##wc(_lz1, X); \
+ if (_lz1 < _lz0) \
+ X##_e++; /* For overflow detection. */ \
_FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
_FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
} \