]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Avoid "inexact" exceptions in i386/x86_64 trunc functions (bug 15479).
authorJoseph Myers <joseph@codesourcery.com>
Mon, 27 Jun 2016 17:26:52 +0000 (17:26 +0000)
committerJoseph Myers <joseph@codesourcery.com>
Mon, 27 Jun 2016 17:26:52 +0000 (17:26 +0000)
As discussed in
<https://sourceware.org/ml/libc-alpha/2016-05/msg00577.html>, TS
18661-1 disallows ceil, floor, round and trunc functions from raising
the "inexact" exception, in accordance with general IEEE 754 semantics
for when that exception is raised.  Fixing this for x87 floating point
is more complicated than for the other versions of these functions,
because they use the frndint instruction that raises "inexact" and
this can only be avoided by saving and restoring the whole
floating-point environment.

As I noted in
<https://sourceware.org/ml/libc-alpha/2016-06/msg00128.html>, I have
now implemented a GCC option -fno-fp-int-builtin-inexact for GCC 7,
such that GCC will inline these functions on x86, without caring about
"inexact", when the default -ffp-int-builtin-inexact is in effect.
This allows users to get optimized code depending on the options they
pass to the compiler, while making the out-of-line functions follow TS
18661-1 semantics and avoid "inexact".

This patch duly fixes the out-of-line trunc function implementations
to avoid "inexact", in the same way as the nearbyint implementations.

I do not know how the performance of implementations such as these
based on saving the environment and changing the rounding mode
temporarily compares to that of the C versions or SSE 4.1 versions (of
course, for 32-bit x86 SSE implementations still need to get the
return value in an x87 register); it's entirely possible other
implementations could be faster in some cases.

Tested for x86_64 and x86.

[BZ #15479]
* sysdeps/i386/fpu/s_trunc.S (__trunc): Save and restore
floating-point environment rather than just control word.
* sysdeps/i386/fpu/s_truncf.S (__truncf): Likewise.
* sysdeps/i386/fpu/s_truncl.S (__truncl): Save and restore
floating-point environment, with "invalid" exceptions merged in,
rather than just control word.
* sysdeps/x86_64/fpu/s_truncl.S (__truncl): Likewise.
* math/libm-test.inc (trunc_test_data): Do not allow spurious
"inexact" exceptions.

ChangeLog
math/libm-test.inc
sysdeps/i386/fpu/s_trunc.S
sysdeps/i386/fpu/s_truncf.S
sysdeps/i386/fpu/s_truncl.S
sysdeps/x86_64/fpu/s_truncl.S

index a67e532b723201ef9657f561a6127cd5997708e7..47c12b4a14cc945ca23ba7771da946a07e53bca4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
 2016-06-27  Joseph Myers  <joseph@codesourcery.com>
 
+       [BZ #15479]
+       * sysdeps/i386/fpu/s_trunc.S (__trunc): Save and restore
+       floating-point environment rather than just control word.
+       * sysdeps/i386/fpu/s_truncf.S (__truncf): Likewise.
+       * sysdeps/i386/fpu/s_truncl.S (__truncl): Save and restore
+       floating-point environment, with "invalid" exceptions merged in,
+       rather than just control word.
+       * sysdeps/x86_64/fpu/s_truncl.S (__truncl): Likewise.
+       * math/libm-test.inc (trunc_test_data): Do not allow spurious
+       "inexact" exceptions.
+
        [BZ #15479]
        * sysdeps/i386/fpu/s_floor.S (__floor): Save and restore
        floating-point environment rather than just control word.
index 9f6e21da5b351375a624db0c8637024768db6576..4ac7a0c80d9fd9d49be3f9bf2f10a7e1a09aa0d9 100644 (file)
@@ -12112,9 +12112,8 @@ static const struct test_f_f_data trunc_test_data[] =
 
     TEST_f_f (trunc, 0, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, minus_zero, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
-    /* Bug 15479: spurious "inexact" exception may occur.  */
-    TEST_f_f (trunc, min_subnorm_value, 0.0, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, min_value, 0.0, ERRNO_UNCHANGED),
+    TEST_f_f (trunc, min_subnorm_value, 0.0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, min_value, 0.0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, 1, 1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, 2, 2, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, 0x1p23, 0x1p23, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
@@ -12133,8 +12132,8 @@ static const struct test_f_f_data trunc_test_data[] =
     TEST_f_f (trunc, 0x1p113, 0x1p113, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, 0x1p114, 0x1p114, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, max_value, max_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
-    TEST_f_f (trunc, -min_subnorm_value, minus_zero, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, -min_value, minus_zero, ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -min_subnorm_value, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -min_value, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, -1, -1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, -2, -2, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, -0x1p23, -0x1p23, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
@@ -12154,108 +12153,108 @@ static const struct test_f_f_data trunc_test_data[] =
     TEST_f_f (trunc, -0x1p114, -0x1p114, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, -max_value, -max_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
 
-    TEST_f_f (trunc, 0.1, 0, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, 0.25, 0, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, 0.625, 0, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, -0.1, minus_zero, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, -0.25, minus_zero, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, -0.625, minus_zero, ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 0.1, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 0.25, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 0.625, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -0.1, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -0.25, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -0.625, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, 1, 1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
     TEST_f_f (trunc, -1, -1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
-    TEST_f_f (trunc, 1.625, 1, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, -1.625, -1, ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 1.625, 1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -1.625, -1, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
 
-    TEST_f_f (trunc, 1048580.625L, 1048580L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, -1048580.625L, -1048580L, ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 1048580.625L, 1048580L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -1048580.625L, -1048580L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
 
-    TEST_f_f (trunc, 8388610.125L, 8388610.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, -8388610.125L, -8388610.0L, ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 8388610.125L, 8388610.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -8388610.125L, -8388610.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
 
-    TEST_f_f (trunc, 4294967296.625L, 4294967296.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, -4294967296.625L, -4294967296.0L, ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 4294967296.625L, 4294967296.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -4294967296.625L, -4294967296.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
 
 #if MANT_DIG >= 64
     /* The result can only be represented in long double.  */
-    TEST_f_f (trunc, 4503599627370495.5L, 4503599627370495.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, 4503599627370496.25L, 4503599627370496.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, 4503599627370496.5L, 4503599627370496.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, 4503599627370496.75L, 4503599627370496.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, 4503599627370497.5L, 4503599627370497.0L, ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 4503599627370495.5L, 4503599627370495.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 4503599627370496.25L, 4503599627370496.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 4503599627370496.5L, 4503599627370496.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 4503599627370496.75L, 4503599627370496.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 4503599627370497.5L, 4503599627370497.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
 
 # if MANT_DIG > 100
-    TEST_f_f (trunc, 4503599627370494.5000000000001L, 4503599627370494.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, 4503599627370495.5000000000001L, 4503599627370495.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, 4503599627370496.5000000000001L, 4503599627370496.0L, ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 4503599627370494.5000000000001L, 4503599627370494.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 4503599627370495.5000000000001L, 4503599627370495.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 4503599627370496.5000000000001L, 4503599627370496.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
 # endif
 
-    TEST_f_f (trunc, -4503599627370495.5L, -4503599627370495.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, -4503599627370496.25L, -4503599627370496.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, -4503599627370496.5L, -4503599627370496.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, -4503599627370496.75L, -4503599627370496.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, -4503599627370497.5L, -4503599627370497.0L, ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -4503599627370495.5L, -4503599627370495.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -4503599627370496.25L, -4503599627370496.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -4503599627370496.5L, -4503599627370496.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -4503599627370496.75L, -4503599627370496.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -4503599627370497.5L, -4503599627370497.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
 
 # if MANT_DIG > 100
-    TEST_f_f (trunc, -4503599627370494.5000000000001L, -4503599627370494.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, -4503599627370495.5000000000001L, -4503599627370495.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, -4503599627370496.5000000000001L, -4503599627370496.0L, ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -4503599627370494.5000000000001L, -4503599627370494.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -4503599627370495.5000000000001L, -4503599627370495.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -4503599627370496.5000000000001L, -4503599627370496.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
 # endif
 
-    TEST_f_f (trunc, 9007199254740991.5L, 9007199254740991.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, 9007199254740992.25L, 9007199254740992.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, 9007199254740992.5L, 9007199254740992.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, 9007199254740992.75L, 9007199254740992.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, 9007199254740993.5L, 9007199254740993.0L, ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 9007199254740991.5L, 9007199254740991.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 9007199254740992.25L, 9007199254740992.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 9007199254740992.5L, 9007199254740992.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 9007199254740992.75L, 9007199254740992.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 9007199254740993.5L, 9007199254740993.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
 
 # if MANT_DIG > 100
-    TEST_f_f (trunc, 9007199254740991.0000000000001L, 9007199254740991.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, 9007199254740992.0000000000001L, 9007199254740992.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, 9007199254740993.0000000000001L, 9007199254740993.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, 9007199254740991.5000000000001L, 9007199254740991.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, 9007199254740992.5000000000001L, 9007199254740992.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, 9007199254740993.5000000000001L, 9007199254740993.0L, ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 9007199254740991.0000000000001L, 9007199254740991.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 9007199254740992.0000000000001L, 9007199254740992.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 9007199254740993.0000000000001L, 9007199254740993.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 9007199254740991.5000000000001L, 9007199254740991.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 9007199254740992.5000000000001L, 9007199254740992.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 9007199254740993.5000000000001L, 9007199254740993.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
 # endif
 
-    TEST_f_f (trunc, -9007199254740991.5L, -9007199254740991.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, -9007199254740992.25L, -9007199254740992.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, -9007199254740992.5L, -9007199254740992.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, -9007199254740992.75L, -9007199254740992.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, -9007199254740993.5L, -9007199254740993.0L, ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -9007199254740991.5L, -9007199254740991.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -9007199254740992.25L, -9007199254740992.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -9007199254740992.5L, -9007199254740992.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -9007199254740992.75L, -9007199254740992.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -9007199254740993.5L, -9007199254740993.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
 
 # if MANT_DIG > 100
-    TEST_f_f (trunc, -9007199254740991.0000000000001L, -9007199254740991.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, -9007199254740992.0000000000001L, -9007199254740992.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, -9007199254740993.0000000000001L, -9007199254740993.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, -9007199254740991.5000000000001L, -9007199254740991.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, -9007199254740992.5000000000001L, -9007199254740992.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, -9007199254740993.5000000000001L, -9007199254740993.0L, ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -9007199254740991.0000000000001L, -9007199254740991.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -9007199254740992.0000000000001L, -9007199254740992.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -9007199254740993.0000000000001L, -9007199254740993.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -9007199254740991.5000000000001L, -9007199254740991.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -9007199254740992.5000000000001L, -9007199254740992.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -9007199254740993.5000000000001L, -9007199254740993.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
 # endif
 
-    TEST_f_f (trunc, 72057594037927935.5L, 72057594037927935.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, 72057594037927936.25L, 72057594037927936.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, 72057594037927936.5L, 72057594037927936.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, 72057594037927936.75L, 72057594037927936.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, 72057594037927937.5L, 72057594037927937.0L, ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 72057594037927935.5L, 72057594037927935.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 72057594037927936.25L, 72057594037927936.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 72057594037927936.5L, 72057594037927936.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 72057594037927936.75L, 72057594037927936.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 72057594037927937.5L, 72057594037927937.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
 
-    TEST_f_f (trunc, -72057594037927935.5L, -72057594037927935.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, -72057594037927936.25L, -72057594037927936.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, -72057594037927936.5L, -72057594037927936.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, -72057594037927936.75L, -72057594037927936.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, -72057594037927937.5L, -72057594037927937.0L, ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -72057594037927935.5L, -72057594037927935.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -72057594037927936.25L, -72057594037927936.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -72057594037927936.5L, -72057594037927936.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -72057594037927936.75L, -72057594037927936.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -72057594037927937.5L, -72057594037927937.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
 
     /* Check cases where first double is a exact integer higher than 2^52 and
        the precision is determined by second long double for IBM long double.  */
-    TEST_f_f (trunc,  34503599627370498.515625L, 34503599627370498.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, -34503599627370498.515625L, -34503599627370498.0L, ERRNO_UNCHANGED),
+    TEST_f_f (trunc,  34503599627370498.515625L, 34503599627370498.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -34503599627370498.515625L, -34503599627370498.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
 # if MANT_DIG >= 106
-    TEST_f_f (trunc,  1192568192774434123539907640624.484375L, 1192568192774434123539907640624.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, -1192568192774434123539907640624.484375L, -1192568192774434123539907640624.0L, ERRNO_UNCHANGED),
+    TEST_f_f (trunc,  1192568192774434123539907640624.484375L, 1192568192774434123539907640624.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, -1192568192774434123539907640624.484375L, -1192568192774434123539907640624.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
 # endif
 
-    TEST_f_f (trunc, 10141204801825835211973625643007.5L, 10141204801825835211973625643007.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, 10141204801825835211973625643008.25L, 10141204801825835211973625643008.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, 10141204801825835211973625643008.5L, 10141204801825835211973625643008.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, 10141204801825835211973625643008.75L, 10141204801825835211973625643008.0L, ERRNO_UNCHANGED),
-    TEST_f_f (trunc, 10141204801825835211973625643009.5L, 10141204801825835211973625643009.0L, ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 10141204801825835211973625643007.5L, 10141204801825835211973625643007.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 10141204801825835211973625643008.25L, 10141204801825835211973625643008.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 10141204801825835211973625643008.5L, 10141204801825835211973625643008.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 10141204801825835211973625643008.75L, 10141204801825835211973625643008.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+    TEST_f_f (trunc, 10141204801825835211973625643009.5L, 10141204801825835211973625643009.0L, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
 #endif
   };
 
index a15e5e5f167386d492d5dd54280cf31b0c5172e7..8d9a6df0283372f19206e4345833cac3bb502059 100644 (file)
 
 ENTRY(__trunc)
        fldl    4(%esp)
-       subl    $8, %esp
-       cfi_adjust_cfa_offset (8)
-       fstcw   4(%esp)
+       subl    $32, %esp
+       cfi_adjust_cfa_offset (32)
+       fnstenv 4(%esp)
        movl    $0xc00, %edx
        orl     4(%esp), %edx
        movl    %edx, (%esp)
        fldcw   (%esp)
        frndint
-       fldcw   4(%esp)
-       addl    $8, %esp
-       cfi_adjust_cfa_offset (-8)
+       fldenv  4(%esp)
+       addl    $32, %esp
+       cfi_adjust_cfa_offset (-32)
        ret
 END(__trunc)
 weak_alias (__trunc, trunc)
index cbf257a9496913258737bd84060aa07817550cdf..d55a11d393d8179d4e67fd341f24df03ca5e1540 100644 (file)
 
 ENTRY(__truncf)
        flds    4(%esp)
-       subl    $8, %esp
-       cfi_adjust_cfa_offset (8)
-       fstcw   4(%esp)
+       subl    $32, %esp
+       cfi_adjust_cfa_offset (32)
+       fnstenv 4(%esp)
        movl    $0xc00, %edx
        orl     4(%esp), %edx
        movl    %edx, (%esp)
        fldcw   (%esp)
        frndint
-       fldcw   4(%esp)
-       addl    $8, %esp
-       cfi_adjust_cfa_offset (-8)
+       fldenv  4(%esp)
+       addl    $32, %esp
+       cfi_adjust_cfa_offset (-32)
        ret
 END(__truncf)
 weak_alias (__truncf, truncf)
index f92b474d492cf49d6e4fde2a8a05fed5a0f86dce..f5ba37297680eabf759388bdca110b8c9f925843 100644 (file)
 
 ENTRY(__truncl)
        fldt    4(%esp)
-       subl    $8, %esp
-       cfi_adjust_cfa_offset (8)
-       fstcw   4(%esp)
+       subl    $32, %esp
+       cfi_adjust_cfa_offset (32)
+       fnstenv 4(%esp)
        movl    $0xc00, %edx
        orl     4(%esp), %edx
        movl    %edx, (%esp)
        fldcw   (%esp)
        frndint
-       fldcw   4(%esp)
-       addl    $8, %esp
-       cfi_adjust_cfa_offset (-8)
+       fnstsw
+       andl    $0x1, %eax
+       orl     %eax, 8(%esp)
+       fldenv  4(%esp)
+       addl    $32, %esp
+       cfi_adjust_cfa_offset (-32)
        ret
 END(__truncl)
 weak_alias (__truncl, truncl)
index c37cf00241d86c255fbf7c1b4d95d8f6962d08ba..0b46efec5391e4c1528d955bc595150a06b80507 100644 (file)
 
 ENTRY(__truncl)
        fldt    8(%rsp)
-       fstcw   -4(%rsp)
+       fnstenv -28(%rsp)
        movl    $0xc00, %edx
-       orl     -4(%rsp), %edx
-       movl    %edx, -8(%rsp)
-       fldcw   -8(%rsp)
+       orl     -28(%rsp), %edx
+       movl    %edx, -32(%rsp)
+       fldcw   -32(%rsp)
        frndint
-       fldcw   -4(%rsp)
+       fnstsw
+       andl    $0x1, %eax
+       orl     %eax, -24(%rsp)
+       fldenv  -28(%rsp)
        ret
 END(__truncl)
 weak_alias (__truncl, truncl)