From patchwork Wed Jun 22 17:22:52 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joseph Myers X-Patchwork-Id: 13309 Received: (qmail 27307 invoked by alias); 22 Jun 2016 17:23:08 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 27279 invoked by uid 89); 22 Jun 2016 17:23:07 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL, BAYES_00, KAM_LOTSOFHASH, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=no version=3.3.2 spammy=caring, raising, 754, duly X-HELO: relay1.mentorg.com Date: Wed, 22 Jun 2016 17:22:52 +0000 From: Joseph Myers To: Subject: Avoid "inexact" exceptions in i386/x86_64 trunc functions (bug 15479) Message-ID: User-Agent: Alpine 2.20 (DEB 67 2015-01-07) MIME-Version: 1.0 As discussed in , 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 , 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. I intend to commit this, and corresponding ceil and floor fixes, in the absence of further comments. 2016-06-22 Joseph Myers [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. diff --git a/math/libm-test.inc b/math/libm-test.inc index 17d65b4..a4983b6 100644 --- a/math/libm-test.inc +++ b/math/libm-test.inc @@ -11827,9 +11827,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), @@ -11848,8 +11847,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), @@ -11869,108 +11868,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 }; diff --git a/sysdeps/i386/fpu/s_trunc.S b/sysdeps/i386/fpu/s_trunc.S index a15e5e5..8d9a6df 100644 --- a/sysdeps/i386/fpu/s_trunc.S +++ b/sysdeps/i386/fpu/s_trunc.S @@ -21,17 +21,17 @@ 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) diff --git a/sysdeps/i386/fpu/s_truncf.S b/sysdeps/i386/fpu/s_truncf.S index cbf257a..d55a11d 100644 --- a/sysdeps/i386/fpu/s_truncf.S +++ b/sysdeps/i386/fpu/s_truncf.S @@ -21,17 +21,17 @@ 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) diff --git a/sysdeps/i386/fpu/s_truncl.S b/sysdeps/i386/fpu/s_truncl.S index f92b474..f5ba372 100644 --- a/sysdeps/i386/fpu/s_truncl.S +++ b/sysdeps/i386/fpu/s_truncl.S @@ -21,17 +21,20 @@ 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) diff --git a/sysdeps/x86_64/fpu/s_truncl.S b/sysdeps/x86_64/fpu/s_truncl.S index c37cf00..0b46efe 100644 --- a/sysdeps/x86_64/fpu/s_truncl.S +++ b/sysdeps/x86_64/fpu/s_truncl.S @@ -21,13 +21,16 @@ 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)