From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5589 invoked by alias); 15 Mar 2007 17:15:43 -0000 Received: (qmail 5572 invoked by uid 22791); 15 Mar 2007 17:15:42 -0000 X-Spam-Check-By: sourceware.org Received: from sunsite.ms.mff.cuni.cz (HELO sunsite.mff.cuni.cz) (195.113.15.26) by sourceware.org (qpsmtpd/0.31) with ESMTP; Thu, 15 Mar 2007 17:15:36 +0000 Received: from sunsite.mff.cuni.cz (localhost.localdomain [127.0.0.1]) by sunsite.mff.cuni.cz (8.13.8/8.13.8) with ESMTP id l2FHJO0v012563; Thu, 15 Mar 2007 18:19:24 +0100 Received: (from jakub@localhost) by sunsite.mff.cuni.cz (8.13.8/8.13.8/Submit) id l2FHJOd8012561; Thu, 15 Mar 2007 18:19:24 +0100 Date: Thu, 15 Mar 2007 17:15:00 -0000 From: Jakub Jelinek To: Ulrich Drepper Cc: Glibc hackers Subject: [PATCH] Fix i386/x86_64 log{,10,2,1p}{,f,l} Message-ID: <20070315171923.GP1826@sunsite.mff.cuni.cz> Reply-To: Jakub Jelinek Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit User-Agent: Mutt/1.4.2.2i Mailing-List: contact libc-hacker-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-hacker-owner@sourceware.org X-SW-Source: 2007-03/txt/msg00024.txt.bz2 Hi! As the added tests show, we had some issues in hand written log* assembly: 1) logl(NAN) on x86_64 and log{,f,l}(NAN) on i386 raised FE_INVALID, while it shouldn't, at least neither Domain nor Pole error is documented for x is NaN case in http://www.opengroup.org/onlinepubs/009695399/functions/logl.html 2) log{2,10}l(-HUGE_VALL) on x86_64 didn't raise FE_INVALID, while it was supposed to (Domain error is documented for that the same as it is for negative finite arguments) 3) log1pl(-HUGE_VALL) returned -HUGE_VALL instead of NAN and didn't raise FE_INVALID on x86_64 2) and 3) were caused by broken conversion from sahf: the original i386 code did: sahf; jc 3f; 4: ... 3: jp 4b; (wanted to execute code after jp only for NaN (i.e. (%ah & 0x45) == 1) and code at 4: for other cases. This was converted to andb $1, %ah; jnz 3f; 4: ... 3: jp 4b; but of course jp never branched, because the result of andb was always 1. This can be either done as in the patch below (testb $1, %ah; jnz 3f; 4: ... 3: testb $4, %ah; jnz 4b;) or perhaps could be done as shorter (but more insns in the common case) andb $0x45, %ah; cmpb $1, %ah; jz 3f; 4: ... 3: 2007-03-15 Jakub Jelinek [BZ #3919] * math/libm-test.inc (log_test): Test -Inf and NaN. (log10_test, log1p_test, log2_test): Test -Inf. * sysdeps/i386/fpu/e_log.S (__ieee754_log): Don't raise FE_INVALID when argument is qNaN. * sysdeps/i386/fpu/e_logl.S (__ieee754_logl): Likewise. * sysdeps/i386/fpu/e_logf.S (__ieee754_logf): Likewise. * sysdeps/x86_64/fpu/e_logl.S (__ieee754_logl): Likewise. * sysdeps/x86_64/fpu/e_log10l.S (__ieee754_log10l): Replace andb $1, %ah with testb $1, %ah, don't test for parity, instead testb $4, %ah and jump if non-zero. * sysdeps/x86_64/fpu/e_log2l.S (__ieee754_log2l): Likewise. * sysdeps/x86_64/fpu/s_log1pl.S (__log1pl): Likewise. --- libc/math/libm-test.inc.jj 2007-03-13 17:42:15.000000000 +0100 +++ libc/math/libm-test.inc 2007-03-15 16:14:28.000000000 +0100 @@ -4127,7 +4127,9 @@ log_test (void) TEST_f_f (log, 1, 0); TEST_f_f (log, -1, nan_value, INVALID_EXCEPTION); + TEST_f_f (log, minus_infty, nan_value, INVALID_EXCEPTION); TEST_f_f (log, plus_infty, plus_infty); + TEST_f_f (log, nan_value, nan_value); TEST_f_f (log, M_El, 1); TEST_f_f (log, 1.0 / M_El, -1); @@ -4157,6 +4159,7 @@ log10_test (void) /* log10 (x) == NaN plus invalid exception if x < 0. */ TEST_f_f (log10, -1, nan_value, INVALID_EXCEPTION); + TEST_f_f (log10, minus_infty, nan_value, INVALID_EXCEPTION); TEST_f_f (log10, plus_infty, plus_infty); TEST_f_f (log10, nan_value, nan_value); @@ -4188,6 +4191,7 @@ log1p_test (void) TEST_f_f (log1p, -1, minus_infty, DIVIDE_BY_ZERO_EXCEPTION); TEST_f_f (log1p, -2, nan_value, INVALID_EXCEPTION); + TEST_f_f (log1p, minus_infty, nan_value, INVALID_EXCEPTION); TEST_f_f (log1p, plus_infty, plus_infty); TEST_f_f (log1p, nan_value, nan_value); @@ -4218,6 +4222,7 @@ log2_test (void) TEST_f_f (log2, 1, 0); TEST_f_f (log2, -1, nan_value, INVALID_EXCEPTION); + TEST_f_f (log2, minus_infty, nan_value, INVALID_EXCEPTION); TEST_f_f (log2, plus_infty, plus_infty); TEST_f_f (log2, nan_value, nan_value); --- libc/sysdeps/i386/fpu/e_log.S.jj 2005-05-04 19:45:15.000000000 +0200 +++ libc/sysdeps/i386/fpu/e_log.S 2007-03-15 17:57:18.000000000 +0100 @@ -36,11 +36,15 @@ limit: .double 0.29 ENTRY(__ieee754_log) fldln2 // log(2) fldl 4(%esp) // x : log(2) + fxam + fnstsw #ifdef PIC LOAD_PIC_REG (dx) #endif fld %st // x : x : log(2) - fsubl MO(one) // x-1 : x : log(2) + sahf + jc 3f // in case x is NaN or +-Inf +4: fsubl MO(one) // x-1 : x : log(2) fld %st // x-1 : x-1 : x : log(2) fabs // |x-1| : x-1 : x : log(2) fcompl MO(limit) // x-1 : x : log(2) @@ -54,4 +58,9 @@ ENTRY(__ieee754_log) 2: fstp %st(0) // x : log(2) fyl2x // log(x) ret + +3: jp 4b // in case x is +-Inf + fstp %st(1) + fstp %st(1) + ret END (__ieee754_log) --- libc/sysdeps/i386/fpu/e_logf.S.jj 2005-05-04 19:45:15.000000000 +0200 +++ libc/sysdeps/i386/fpu/e_logf.S 2007-03-15 17:56:15.000000000 +0100 @@ -37,11 +37,15 @@ limit: .double 0.29 ENTRY(__ieee754_logf) fldln2 // log(2) flds 4(%esp) // x : log(2) + fxam + fnstsw #ifdef PIC LOAD_PIC_REG (dx) #endif fld %st // x : x : log(2) - fsubl MO(one) // x-1 : x : log(2) + sahf + jc 3f // in case x is NaN or +-Inf +4: fsubl MO(one) // x-1 : x : log(2) fld %st // x-1 : x-1 : x : log(2) fabs // |x-1| : x-1 : x : log(2) fcompl MO(limit) // x-1 : x : log(2) @@ -55,4 +59,9 @@ ENTRY(__ieee754_logf) 2: fstp %st(0) // x : log(2) fyl2x // log(x) ret + +3: jp 4b // in case x is +-Inf + fstp %st(1) + fstp %st(1) + ret END (__ieee754_logf) --- libc/sysdeps/i386/fpu/e_logl.S.jj 2005-05-04 19:45:15.000000000 +0200 +++ libc/sysdeps/i386/fpu/e_logl.S 2007-03-15 17:54:29.000000000 +0100 @@ -37,11 +37,15 @@ limit: .double 0.29 ENTRY(__ieee754_logl) fldln2 // log(2) fldt 4(%esp) // x : log(2) + fxam + fnstsw #ifdef PIC LOAD_PIC_REG (dx) #endif fld %st // x : x : log(2) - fsubl MO(one) // x-1 : x : log(2) + sahf + jc 3f // in case x is NaN or +-Inf +4: fsubl MO(one) // x-1 : x : log(2) fld %st // x-1 : x-1 : x : log(2) fabs // |x-1| : x-1 : x : log(2) fcompl MO(limit) // x-1 : x : log(2) @@ -55,4 +59,9 @@ ENTRY(__ieee754_logl) 2: fstp %st(0) // x : log(2) fyl2x // log(x) ret + +3: jp 4b // in case x is +-Inf + fstp %st(1) + fstp %st(1) + ret END (__ieee754_logl) --- libc/sysdeps/x86_64/fpu/s_log1pl.S.jj 2001-09-19 12:24:08.000000000 +0200 +++ libc/sysdeps/x86_64/fpu/s_log1pl.S 2007-03-15 17:47:56.000000000 +0100 @@ -45,7 +45,7 @@ ENTRY(__log1pl) fxam fnstsw fld %st - andb $1,%ah + testb $1, %ah jnz 3f // in case x is NaN or ±Inf 4: fabs @@ -62,7 +62,8 @@ ENTRY(__log1pl) 2: fyl2xp1 ret -3: jp 4b // in case x is ±Inf +3: testb $4, %ah + jnz 4b // in case x is ±Inf fstp %st(1) fstp %st(1) ret --- libc/sysdeps/x86_64/fpu/e_log10l.S.jj 2001-09-19 12:24:08.000000000 +0200 +++ libc/sysdeps/x86_64/fpu/e_log10l.S 2007-03-15 17:46:02.000000000 +0100 @@ -42,7 +42,7 @@ ENTRY(__ieee754_log10l) fxam fnstsw fld %st // x : x : log10(2) - andb $1,%ah + testb $1, %ah jnz 3f // in case x is NaN or ±Inf 4: fsubl MO(one) // x-1 : x : log10(2) fld %st // x-1 : x-1 : x : log10(2) @@ -59,7 +59,8 @@ ENTRY(__ieee754_log10l) fyl2x // log10(x) ret -3: jp 4b // in case x is ±Inf +3: testb $4, %ah + jnz 4b // in case x is ±Inf fstp %st(1) fstp %st(1) ret --- libc/sysdeps/x86_64/fpu/e_log2l.S.jj 2001-09-19 12:24:08.000000000 +0200 +++ libc/sysdeps/x86_64/fpu/e_log2l.S 2007-03-15 17:45:27.000000000 +0100 @@ -39,7 +39,7 @@ ENTRY(__ieee754_log2l) fxam fnstsw fld %st // x : x : 1 - andb $1,%ah + testb $1, %ah jnz 3f // in case x is NaN or ±Inf 4: fsub %st(2), %st // x-1 : x : 1 fld %st // x-1 : x-1 : x : 1 @@ -56,7 +56,8 @@ ENTRY(__ieee754_log2l) fyl2x // log(x) ret -3: jp 4b // in case x is ±Inf +3: testb $4, %ah + jnz 4b // in case x is ±Inf fstp %st(1) fstp %st(1) ret --- libc/sysdeps/x86_64/fpu/e_logl.S.jj 2001-09-19 12:24:08.000000000 +0200 +++ libc/sysdeps/x86_64/fpu/e_logl.S 2007-03-15 17:46:16.000000000 +0100 @@ -38,8 +38,12 @@ limit: .double 0.29 ENTRY(__ieee754_logl) fldln2 // log(2) fldt 8(%rsp) // x : log(2) + fxam + fnstsw fld %st // x : x : log(2) - fsubl MO(one) // x-1 : x : log(2) + testb $1, %ah + jnz 3f // in case x is NaN or +-Inf +4: fsubl MO(one) // x-1 : x : log(2) fld %st // x-1 : x-1 : x : log(2) fabs // |x-1| : x-1 : x : log(2) fcompl MO(limit) // x-1 : x : log(2) @@ -53,4 +57,10 @@ ENTRY(__ieee754_logl) 2: fstp %st(0) // x : log(2) fyl2x // log(x) ret + +3: testb $4, %ah + jnz 4b // in case x is +-Inf + fstp %st(1) + fstp %st(1) + ret END (__ieee754_logl) Jakub