Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 200877 Details for
Bug 264335
sys-libs/glibc: floor/ceil/rint give incorrect results on Alpha
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
patch to fix floor, ceil, rint on alpha
fix-floor.patch (text/plain), 7.95 KB, created by
Matt Turner
on 2009-08-11 00:27:48 UTC
(
hide
)
Description:
patch to fix floor, ceil, rint on alpha
Filename:
MIME Type:
Creator:
Matt Turner
Created:
2009-08-11 00:27:48 UTC
Size:
7.95 KB
patch
obsolete
>diff -ur glibc-2.9-20081201.old/sysdeps/alpha/fpu/s_ceil.c glibc-2.9-20081201/sysdeps/alpha/fpu/s_ceil.c >--- glibc-2.9-20081201.old/sysdeps/alpha/fpu/s_ceil.c 2009-08-10 20:12:12.117316000 -0400 >+++ glibc-2.9-20081201/sysdeps/alpha/fpu/s_ceil.c 2009-08-10 20:14:04.947138000 -0400 >@@ -27,20 +27,25 @@ > double > __ceil (double x) > { >- double two52 = copysign (0x1.0p52, x); >- double r, tmp; >- >- __asm ( >+ if (isless (fabs (x), 9007199254740992.0)) /* 1 << DBL_MANT_DIG */ >+ { >+ double tmp1, new_x; >+ >+ new_x = -x; >+ __asm ( > #ifdef _IEEE_FP_INEXACT >- "addt/suim %2, %3, %1\n\tsubt/suim %1, %3, %0" >+ "cvttq/svim %2,%1\n\t" > #else >- "addt/sum %2, %3, %1\n\tsubt/sum %1, %3, %0" >+ "cvttq/svm %2,%1\n\t" > #endif >- : "=&f"(r), "=&f"(tmp) >- : "f"(-x), "f"(-two52)); >+ "cvtqt/m %1,%0\n\t" >+ : "=f"(new_x), "=&f"(tmp1) >+ : "f"(new_x)); > >- /* Fix up the negation we did above, as well as handling -0 properly. */ >- return copysign (r, x); >+ /* Fix up the negation we did above, as well as handling -0 properly. */ >+ x = copysign(new_x, x); >+ } >+ return x; > } > > weak_alias (__ceil, ceil) >diff -ur glibc-2.9-20081201.old/sysdeps/alpha/fpu/s_ceilf.c glibc-2.9-20081201/sysdeps/alpha/fpu/s_ceilf.c >--- glibc-2.9-20081201.old/sysdeps/alpha/fpu/s_ceilf.c 2009-08-10 20:12:12.120247000 -0400 >+++ glibc-2.9-20081201/sysdeps/alpha/fpu/s_ceilf.c 2009-08-10 20:14:04.948115000 -0400 >@@ -26,20 +26,30 @@ > float > __ceilf (float x) > { >- float two23 = copysignf (0x1.0p23, x); >- float r, tmp; >- >- __asm ( >+ if (isless (fabsf (x), 16777216.0f)) /* 1 << FLT_MANT_DIG */ >+ { >+ /* Note that Alpha S_Floating is stored in registers in a >+ restricted T_Floating format, so we don't even need to >+ convert back to S_Floating in the end. The initial >+ conversion to T_Floating is needed to handle denormals. */ >+ >+ float tmp1, tmp2, new_x; >+ >+ new_x = -x; >+ __asm ("cvtst/s %3,%2\n\t" > #ifdef _IEEE_FP_INEXACT >- "adds/suim %2, %3, %1\n\tsubs/suim %1, %3, %0" >+ "cvttq/svim %2,%1\n\t" > #else >- "adds/sum %2, %3, %1\n\tsubs/sum %1, %3, %0" >+ "cvttq/svm %2,%1\n\t" > #endif >- : "=&f"(r), "=&f"(tmp) >- : "f"(-x), "f"(-two23)); >+ "cvtqt/m %1,%0\n\t" >+ : "=f"(new_x), "=&f"(tmp1), "=&f"(tmp2) >+ : "f"(new_x)); > >- /* Fix up the negation we did above, as well as handling -0 properly. */ >- return copysignf (r, x); >+ /* Fix up the negation we did above, as well as handling -0 properly. */ >+ x = copysignf(new_x, x); >+ } >+ return x; > } > > weak_alias (__ceilf, ceilf) >diff -ur glibc-2.9-20081201.old/sysdeps/alpha/fpu/s_floor.c glibc-2.9-20081201/sysdeps/alpha/fpu/s_floor.c >--- glibc-2.9-20081201.old/sysdeps/alpha/fpu/s_floor.c 2009-08-10 20:12:12.119270000 -0400 >+++ glibc-2.9-20081201/sysdeps/alpha/fpu/s_floor.c 2009-08-10 20:14:04.949092000 -0400 >@@ -21,26 +21,32 @@ > #include <math_ldbl_opt.h> > > >-/* Use the -inf rounding mode conversion instructions to implement floor. */ >+/* Use the -inf rounding mode conversion instructions to implement >+ floor. We note when the exponent is large enough that the value >+ must be integral, as this avoids unpleasant integer overflows. */ > > double > __floor (double x) > { >- double two52 = copysign (0x1.0p52, x); >- double r, tmp; >- >- __asm ( >+ if (isless (fabs (x), 9007199254740992.0)) /* 1 << DBL_MANT_DIG */ >+ { >+ double tmp1, new_x; >+ >+ __asm ( > #ifdef _IEEE_FP_INEXACT >- "addt/suim %2, %3, %1\n\tsubt/suim %1, %3, %0" >+ "cvttq/svim %2,%1\n\t" > #else >- "addt/sum %2, %3, %1\n\tsubt/sum %1, %3, %0" >+ "cvttq/svm %2,%1\n\t" > #endif >- : "=&f"(r), "=&f"(tmp) >- : "f"(x), "f"(two52)); >+ "cvtqt/m %1,%0\n\t" >+ : "=f"(new_x), "=&f"(tmp1) >+ : "f"(x)); > >- /* floor(-0) == -0, and in general we'll always have the same >- sign as our input. */ >- return copysign (r, x); >+ /* floor(-0) == -0, and in general we'll always have the same >+ sign as our input. */ >+ x = copysign(new_x, x); >+ } >+ return x; > } > > weak_alias (__floor, floor) >diff -ur glibc-2.9-20081201.old/sysdeps/alpha/fpu/s_floorf.c glibc-2.9-20081201/sysdeps/alpha/fpu/s_floorf.c >--- glibc-2.9-20081201.old/sysdeps/alpha/fpu/s_floorf.c 2009-08-10 20:12:12.118293000 -0400 >+++ glibc-2.9-20081201/sysdeps/alpha/fpu/s_floorf.c 2009-08-10 20:14:04.950069000 -0400 >@@ -20,26 +20,37 @@ > #include <math.h> > > >-/* Use the -inf rounding mode conversion instructions to implement floor. */ >+/* Use the -inf rounding mode conversion instructions to implement >+ floor. We note when the exponent is large enough that the value >+ must be integral, as this avoids unpleasant integer overflows. */ > > float > __floorf (float x) > { >- float two23 = copysignf (0x1.0p23, x); >- float r, tmp; >- >- __asm ( >+ if (isless (fabsf (x), 16777216.0f)) /* 1 << FLT_MANT_DIG */ >+ { >+ /* Note that Alpha S_Floating is stored in registers in a >+ restricted T_Floating format, so we don't even need to >+ convert back to S_Floating in the end. The initial >+ conversion to T_Floating is needed to handle denormals. */ >+ >+ float tmp1, tmp2, new_x; >+ >+ __asm ("cvtst/s %3,%2\n\t" > #ifdef _IEEE_FP_INEXACT >- "adds/suim %2, %3, %1\n\tsubs/suim %1, %3, %0" >+ "cvttq/svim %2,%1\n\t" > #else >- "adds/sum %2, %3, %1\n\tsubs/sum %1, %3, %0" >+ "cvttq/svm %2,%1\n\t" > #endif >- : "=&f"(r), "=&f"(tmp) >- : "f"(x), "f"(two23)); >+ "cvtqt/m %1,%0\n\t" >+ : "=f"(new_x), "=&f"(tmp1), "=&f"(tmp2) >+ : "f"(x)); > >- /* floor(-0) == -0, and in general we'll always have the same >- sign as our input. */ >- return copysignf (r, x); >+ /* floor(-0) == -0, and in general we'll always have the same >+ sign as our input. */ >+ x = copysignf(new_x, x); >+ } >+ return x; > } > > weak_alias (__floorf, floorf) >diff -ur glibc-2.9-20081201.old/sysdeps/alpha/fpu/s_rint.c glibc-2.9-20081201/sysdeps/alpha/fpu/s_rint.c >--- glibc-2.9-20081201.old/sysdeps/alpha/fpu/s_rint.c 2009-08-10 20:12:12.119270000 -0400 >+++ glibc-2.9-20081201/sysdeps/alpha/fpu/s_rint.c 2009-08-10 20:14:04.951046000 -0400 >@@ -24,15 +24,24 @@ > double > __rint (double x) > { >- double two52 = copysign (0x1.0p52, x); >- double r; >- >- r = x + two52; >- r = r - two52; >+ if (isless (fabs (x), 9007199254740992.0)) /* 1 << DBL_MANT_DIG */ >+ { >+ double tmp1, new_x; >+ __asm ( >+#ifdef _IEEE_FP_INEXACT >+ "cvttq/svid %2,%1\n\t" >+#else >+ "cvttq/svd %2,%1\n\t" >+#endif >+ "cvtqt/d %1,%0\n\t" >+ : "=f"(new_x), "=&f"(tmp1) >+ : "f"(x)); > >- /* rint(-0.1) == -0, and in general we'll always have the same sign >- as our input. */ >- return copysign (r, x); >+ /* rint(-0.1) == -0, and in general we'll always have the same >+ sign as our input. */ >+ x = copysign(new_x, x); >+ } >+ return x; > } > > weak_alias (__rint, rint) >diff -ur glibc-2.9-20081201.old/sysdeps/alpha/fpu/s_rintf.c glibc-2.9-20081201/sysdeps/alpha/fpu/s_rintf.c >--- glibc-2.9-20081201.old/sysdeps/alpha/fpu/s_rintf.c 2009-08-10 20:12:12.116339000 -0400 >+++ glibc-2.9-20081201/sysdeps/alpha/fpu/s_rintf.c 2009-08-10 20:14:04.952023000 -0400 >@@ -23,15 +23,30 @@ > float > __rintf (float x) > { >- float two23 = copysignf (0x1.0p23, x); >- float r; >+ if (isless (fabsf (x), 16777216.0f)) /* 1 << FLT_MANT_DIG */ >+ { >+ /* Note that Alpha S_Floating is stored in registers in a >+ restricted T_Floating format, so we don't even need to >+ convert back to S_Floating in the end. The initial >+ conversion to T_Floating is needed to handle denormals. */ > >- r = x + two23; >- r = r - two23; >+ float tmp1, tmp2, new_x; > >- /* rint(-0.1) == -0, and in general we'll always have the same sign >- as our input. */ >- return copysign (r, x); >+ __asm ("cvtst/s %3,%2\n\t" >+#ifdef _IEEE_FP_INEXACT >+ "cvttq/svid %2,%1\n\t" >+#else >+ "cvttq/svd %2,%1\n\t" >+#endif >+ "cvtqt/d %1,%0\n\t" >+ : "=f"(new_x), "=&f"(tmp1), "=&f"(tmp2) >+ : "f"(x)); >+ >+ /* rint(-0.1) == -0, and in general we'll always have the same >+ sign as our input. */ >+ x = copysignf(new_x, x); >+ } >+ return x; > } > > weak_alias (__rintf, rintf)
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 264335
: 200877