summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcus Shawcroft <marcus.shawcroft@linaro.org>2012-11-13 17:01:05 +0000
committerMarcus Shawcroft <marcus.shawcroft@linaro.org>2012-11-13 17:01:05 +0000
commit47594329a9c03fb945f41c19f06401271f9aa9c5 (patch)
tree446ca8eacfca3054d9243cdff7914fa9c134ac68
parent640ac3f1bf2e575b514645fc03cceeeacf7bd845 (diff)
downloadglibc-47594329a9c03fb945f41c19f06401271f9aa9c5.tar.gz
Fix missing truncation UNDERFLOW.
-rw-r--r--ChangeLog7
-rw-r--r--soft-fp/op-common.h25
-rw-r--r--soft-fp/soft-fp.h34
3 files changed, 36 insertions, 30 deletions
diff --git a/ChangeLog b/ChangeLog
index ba9ecf3072..b3bd03f820 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2012-11-13 Marcus Shawcroft <marcus.shawcroft@linaro.org>
+
+ * soft-fp/op-common.h (_FP_PACK_SEMIRAW): Move underflow
+ detection to immediately after _FP_ROUND().
+ * soft-fp/soft-fp.h (_FP_ROUND): Don't round if working
+ bits are 0.
+
2012-11-11 David S. Miller <davem@davemloft.net>
* sysdeps/unix/sysv/linux/sparc/sparc64/get_clockfreq.c: Include
diff --git a/soft-fp/op-common.h b/soft-fp/op-common.h
index db75af53e6..12fb16e5ef 100644
--- a/soft-fp/op-common.h
+++ b/soft-fp/op-common.h
@@ -134,6 +134,12 @@ do { \
#define _FP_PACK_SEMIRAW(fs, wc, X) \
do { \
_FP_ROUND(wc, X); \
+ if (X##_e == 0 && !_FP_FRAC_ZEROP_##wc(X)) \
+ { \
+ if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) \
+ || (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)) \
+ FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \
+ } \
if (_FP_FRAC_HIGH_##fs(X) \
& (_FP_OVERFLOW_##fs >> 1)) \
{ \
@@ -143,24 +149,15 @@ do { \
_FP_OVERFLOW_SEMIRAW(fs, wc, X); \
} \
_FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
- if (!_FP_EXP_NORMAL(fs, wc, X) && !_FP_FRAC_ZEROP_##wc(X)) \
+ if (X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \
{ \
- if (X##_e == 0) \
+ if (!_FP_KEEPNANFRACP) \
{ \
- if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) \
- || (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)) \
- FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \
+ _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \
+ X##_s = _FP_NANSIGN_##fs; \
} \
else \
- { \
- if (!_FP_KEEPNANFRACP) \
- { \
- _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \
- X##_s = _FP_NANSIGN_##fs; \
- } \
- else \
- _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs; \
- } \
+ _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs; \
} \
} while (0)
diff --git a/soft-fp/soft-fp.h b/soft-fp/soft-fp.h
index 750c7fea2d..49a87706cc 100644
--- a/soft-fp/soft-fp.h
+++ b/soft-fp/soft-fp.h
@@ -158,22 +158,24 @@ do { \
#define _FP_ROUND(wc, X) \
do { \
if (_FP_FRAC_LOW_##wc(X) & 7) \
- FP_SET_EXCEPTION(FP_EX_INEXACT); \
- switch (FP_ROUNDMODE) \
- { \
- case FP_RND_NEAREST: \
- _FP_ROUND_NEAREST(wc,X); \
- break; \
- case FP_RND_ZERO: \
- _FP_ROUND_ZERO(wc,X); \
- break; \
- case FP_RND_PINF: \
- _FP_ROUND_PINF(wc,X); \
- break; \
- case FP_RND_MINF: \
- _FP_ROUND_MINF(wc,X); \
- break; \
- } \
+ { \
+ FP_SET_EXCEPTION(FP_EX_INEXACT); \
+ switch (FP_ROUNDMODE) \
+ { \
+ case FP_RND_NEAREST: \
+ _FP_ROUND_NEAREST(wc,X); \
+ break; \
+ case FP_RND_ZERO: \
+ _FP_ROUND_ZERO(wc,X); \
+ break; \
+ case FP_RND_PINF: \
+ _FP_ROUND_PINF(wc,X); \
+ break; \
+ case FP_RND_MINF: \
+ _FP_ROUND_MINF(wc,X); \
+ break; \
+ } \
+ } \
} while (0)
#define FP_CLS_NORMAL 0