summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog33
-rw-r--r--soft-fp/op-common.h35
-rw-r--r--soft-fp/soft-fp.h3
-rw-r--r--sysdeps/aarch64/soft-fp/sfp-machine.h2
-rw-r--r--sysdeps/alpha/soft-fp/sfp-machine.h2
-rw-r--r--sysdeps/arm/soft-fp/sfp-machine.h2
-rw-r--r--sysdeps/mips/mips64/soft-fp/sfp-machine.h2
-rw-r--r--sysdeps/mips/soft-fp/sfp-machine.h2
-rw-r--r--sysdeps/powerpc/soft-fp/sfp-machine.h2
-rw-r--r--sysdeps/sh/soft-fp/sfp-machine.h2
-rw-r--r--sysdeps/sparc/sparc32/soft-fp/sfp-machine.h2
-rw-r--r--sysdeps/sparc/sparc64/soft-fp/sfp-machine.h2
-rw-r--r--sysdeps/tile/sfp-machine.h2
13 files changed, 87 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index ffdb54696c..a7dc412492 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,36 @@
+2014-02-12 Joseph Myers <joseph@codesourcery.com>
+
+ * soft-fp/op-common.h (_FP_DECL): Mark exponent as possibly
+ unused.
+ (_FP_PACK_SEMIRAW): Determine tininess based on rounding shifted
+ value if _FP_TININESS_AFTER_ROUNDING and unrounded value is in
+ subnormal range.
+ (_FP_PACK_CANONICAL): Determine tininess based on rounding to
+ normal precision if _FP_TININESS_AFTER_ROUNDING and unrounded
+ value has largest subnormal exponent.
+ * soft-fp/soft-fp.h [FP_NO_EXCEPTIONS]
+ (_FP_TININESS_AFTER_ROUNDING): Undefine and redefine to 0.
+ * sysdeps/aarch64/soft-fp/sfp-machine.h
+ (_FP_TININESS_AFTER_ROUNDING): New macro.
+ * sysdeps/alpha/soft-fp/sfp-machine.h
+ (_FP_TININESS_AFTER_ROUNDING): Likewise.
+ * sysdeps/arm/soft-fp/sfp-machine.h (_FP_TININESS_AFTER_ROUNDING):
+ Likewise.
+ * sysdeps/mips/mips64/soft-fp/sfp-machine.h
+ (_FP_TININESS_AFTER_ROUNDING): Likewise.
+ * sysdeps/mips/soft-fp/sfp-machine.h
+ (_FP_TININESS_AFTER_ROUNDING): Likewise.
+ * sysdeps/powerpc/soft-fp/sfp-machine.h
+ (_FP_TININESS_AFTER_ROUNDING): Likewise.
+ * sysdeps/sh/soft-fp/sfp-machine.h (_FP_TININESS_AFTER_ROUNDING):
+ Likewise.
+ * sysdeps/sparc/sparc32/soft-fp/sfp-machine.h
+ (_FP_TININESS_AFTER_ROUNDING): Likewise.
+ * sysdeps/sparc/sparc64/soft-fp/sfp-machine.h
+ (_FP_TININESS_AFTER_ROUNDING): Likewise.
+ * sysdeps/tile/sfp-machine.h (_FP_TININESS_AFTER_ROUNDING):
+ Likewise.
+
2014-02-12 Dylan Alex Simon <dylan@dylex.net>
[BZ #16545]
diff --git a/soft-fp/op-common.h b/soft-fp/op-common.h
index e901981b95..6f8c1f3cb0 100644
--- a/soft-fp/op-common.h
+++ b/soft-fp/op-common.h
@@ -32,7 +32,7 @@
#define _FP_DECL(wc, X) \
_FP_I_TYPE X##_c __attribute__ ((unused)); \
_FP_I_TYPE X##_s __attribute__ ((unused)); \
- _FP_I_TYPE X##_e; \
+ _FP_I_TYPE X##_e __attribute__ ((unused)); \
_FP_FRAC_DECL_##wc (X)
/* Test whether the qNaN bit denotes a signaling NaN. */
@@ -191,8 +191,22 @@
#define _FP_PACK_SEMIRAW(fs, wc, X) \
do \
{ \
+ int _FP_PACK_SEMIRAW_is_tiny \
+ = X##_e == 0 && !_FP_FRAC_ZEROP_##wc (X); \
+ if (_FP_TININESS_AFTER_ROUNDING \
+ && _FP_PACK_SEMIRAW_is_tiny) \
+ { \
+ FP_DECL_##fs (_FP_PACK_SEMIRAW_T); \
+ _FP_FRAC_COPY_##wc (_FP_PACK_SEMIRAW_T, X); \
+ _FP_PACK_SEMIRAW_T##_s = X##_s; \
+ _FP_PACK_SEMIRAW_T##_e = X##_e; \
+ _FP_FRAC_SLL_##wc (_FP_PACK_SEMIRAW_T, 1); \
+ _FP_ROUND (wc, _FP_PACK_SEMIRAW_T); \
+ if (_FP_FRAC_OVERP_##wc (fs, _FP_PACK_SEMIRAW_T)) \
+ _FP_PACK_SEMIRAW_is_tiny = 0; \
+ } \
_FP_ROUND (wc, X); \
- if (X##_e == 0 && !_FP_FRAC_ZEROP_##wc (X)) \
+ if (_FP_PACK_SEMIRAW_is_tiny) \
{ \
if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) \
|| (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)) \
@@ -279,6 +293,17 @@
else \
{ \
/* we've got a denormalized number */ \
+ int _FP_PACK_CANONICAL_is_tiny = 1; \
+ if (_FP_TININESS_AFTER_ROUNDING && X##_e == 0) \
+ { \
+ FP_DECL_##fs (_FP_PACK_CANONICAL_T); \
+ _FP_FRAC_COPY_##wc (_FP_PACK_CANONICAL_T, X); \
+ _FP_PACK_CANONICAL_T##_s = X##_s; \
+ _FP_PACK_CANONICAL_T##_e = X##_e; \
+ _FP_ROUND (wc, _FP_PACK_CANONICAL_T); \
+ if (_FP_FRAC_OVERP_##wc (fs, _FP_PACK_CANONICAL_T)) \
+ _FP_PACK_CANONICAL_is_tiny = 0; \
+ } \
X##_e = -X##_e + 1; \
if (X##_e <= _FP_WFRACBITS_##fs) \
{ \
@@ -296,8 +321,10 @@
X##_e = 0; \
_FP_FRAC_SRL_##wc (X, _FP_WORKBITS); \
} \
- if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) \
- || (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)) \
+ if (_FP_PACK_CANONICAL_is_tiny \
+ && ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) \
+ || (FP_TRAPPING_EXCEPTIONS \
+ & FP_EX_UNDERFLOW))) \
FP_SET_EXCEPTION (FP_EX_UNDERFLOW); \
} \
else \
diff --git a/soft-fp/soft-fp.h b/soft-fp/soft-fp.h
index c8a98948f8..8d0efa58e7 100644
--- a/soft-fp/soft-fp.h
+++ b/soft-fp/soft-fp.h
@@ -161,6 +161,9 @@
# undef FP_ROUNDMODE
# define FP_ROUNDMODE FP_RND_ZERO
+# undef _FP_TININESS_AFTER_ROUNDING
+# define _FP_TININESS_AFTER_ROUNDING 0
+
#endif
#define _FP_ROUND_NEAREST(wc, X) \
diff --git a/sysdeps/aarch64/soft-fp/sfp-machine.h b/sysdeps/aarch64/soft-fp/sfp-machine.h
index 9bb94e5ccc..3e969952fa 100644
--- a/sysdeps/aarch64/soft-fp/sfp-machine.h
+++ b/sysdeps/aarch64/soft-fp/sfp-machine.h
@@ -60,6 +60,8 @@
#define FP_EX_DIVZERO FE_DIVBYZERO
#define FP_EX_INEXACT FE_INEXACT
+#define _FP_TININESS_AFTER_ROUNDING 0
+
#define FP_INIT_ROUNDMODE \
do { \
_FPU_GETCW (_fcw); \
diff --git a/sysdeps/alpha/soft-fp/sfp-machine.h b/sysdeps/alpha/soft-fp/sfp-machine.h
index cceccafe26..e11a8dd7ca 100644
--- a/sysdeps/alpha/soft-fp/sfp-machine.h
+++ b/sysdeps/alpha/soft-fp/sfp-machine.h
@@ -74,6 +74,8 @@
#define FP_EX_DIVZERO FE_DIVBYZERO
#define FP_EX_INEXACT FE_INEXACT
+#define _FP_TININESS_AFTER_ROUNDING 1
+
#define FP_INIT_ROUNDMODE \
do { \
if (__builtin_expect (_round == 4, 0)) \
diff --git a/sysdeps/arm/soft-fp/sfp-machine.h b/sysdeps/arm/soft-fp/sfp-machine.h
index eba6e35ced..52a08b5298 100644
--- a/sysdeps/arm/soft-fp/sfp-machine.h
+++ b/sysdeps/arm/soft-fp/sfp-machine.h
@@ -47,3 +47,5 @@
} \
R##_c = FP_CLS_NAN; \
} while (0)
+
+#define _FP_TININESS_AFTER_ROUNDING 0
diff --git a/sysdeps/mips/mips64/soft-fp/sfp-machine.h b/sysdeps/mips/mips64/soft-fp/sfp-machine.h
index 5be50927d0..708afc783e 100644
--- a/sysdeps/mips/mips64/soft-fp/sfp-machine.h
+++ b/sysdeps/mips/mips64/soft-fp/sfp-machine.h
@@ -77,6 +77,8 @@
#define FP_EX_DIVZERO FE_DIVBYZERO
#define FP_EX_INEXACT FE_INEXACT
+#define _FP_TININESS_AFTER_ROUNDING 1
+
#ifdef __mips_hard_float
#define FP_INIT_ROUNDMODE \
do { \
diff --git a/sysdeps/mips/soft-fp/sfp-machine.h b/sysdeps/mips/soft-fp/sfp-machine.h
index fff3b3c613..4e23aa8b26 100644
--- a/sysdeps/mips/soft-fp/sfp-machine.h
+++ b/sysdeps/mips/soft-fp/sfp-machine.h
@@ -64,3 +64,5 @@
#define FP_EX_OVERFLOW (1 << 2)
#define FP_EX_UNDERFLOW (1 << 1)
#define FP_EX_INEXACT (1 << 0)
+
+#define _FP_TININESS_AFTER_ROUNDING 1
diff --git a/sysdeps/powerpc/soft-fp/sfp-machine.h b/sysdeps/powerpc/soft-fp/sfp-machine.h
index 35a38b0031..d92a90e3e2 100644
--- a/sysdeps/powerpc/soft-fp/sfp-machine.h
+++ b/sysdeps/powerpc/soft-fp/sfp-machine.h
@@ -41,6 +41,8 @@
R##_c = FP_CLS_NAN; \
} while (0)
+#define _FP_TININESS_AFTER_ROUNDING 0
+
#if defined __NO_FPRS__ && !defined _SOFT_FLOAT
/* Exception flags. We use the bit positions of the appropriate bits
diff --git a/sysdeps/sh/soft-fp/sfp-machine.h b/sysdeps/sh/soft-fp/sfp-machine.h
index 9b9074860f..81474e8a7c 100644
--- a/sysdeps/sh/soft-fp/sfp-machine.h
+++ b/sysdeps/sh/soft-fp/sfp-machine.h
@@ -53,3 +53,5 @@
#define FP_EX_OVERFLOW (1 << 4)
#define FP_EX_UNDERFLOW (1 << 3)
#define FP_EX_INEXACT (1 << 2)
+
+#define _FP_TININESS_AFTER_ROUNDING 1
diff --git a/sysdeps/sparc/sparc32/soft-fp/sfp-machine.h b/sysdeps/sparc/sparc32/soft-fp/sfp-machine.h
index 025b3ab196..b6baa8185f 100644
--- a/sysdeps/sparc/sparc32/soft-fp/sfp-machine.h
+++ b/sysdeps/sparc/sparc32/soft-fp/sfp-machine.h
@@ -185,6 +185,8 @@
#define FP_EX_DIVZERO (1 << 1)
#define FP_EX_INEXACT (1 << 0)
+#define _FP_TININESS_AFTER_ROUNDING 0
+
#define _FP_DECL_EX \
fpu_control_t _fcw __attribute__ ((unused)) = (FP_RND_NEAREST << 30)
diff --git a/sysdeps/sparc/sparc64/soft-fp/sfp-machine.h b/sysdeps/sparc/sparc64/soft-fp/sfp-machine.h
index 9a0384b1d8..80c1ac5d52 100644
--- a/sysdeps/sparc/sparc64/soft-fp/sfp-machine.h
+++ b/sysdeps/sparc/sparc64/soft-fp/sfp-machine.h
@@ -93,6 +93,8 @@ do { \
#define FP_EX_DIVZERO (1 << 1)
#define FP_EX_INEXACT (1 << 0)
+#define _FP_TININESS_AFTER_ROUNDING 0
+
#define _FP_DECL_EX \
fpu_control_t _fcw __attribute__ ((unused)) = (FP_RND_NEAREST << 30)
diff --git a/sysdeps/tile/sfp-machine.h b/sysdeps/tile/sfp-machine.h
index ff8beeffa7..7a1993ea61 100644
--- a/sysdeps/tile/sfp-machine.h
+++ b/sysdeps/tile/sfp-machine.h
@@ -95,3 +95,5 @@
} \
R##_c = FP_CLS_NAN; \
} while (0)
+
+#define _FP_TININESS_AFTER_ROUNDING 0