| ripped from Debian |
| |
| this change was made to generic __nexttowardf, but not the long double version |
| |
| 2008-05-05 Aurelien Jarno <aurelien@aurel32.net> |
| |
| * sysdeps/ieee754/ldbl-128/s_nexttowardf.c: Include float.h. |
| (__nexttowardf): Use math_opt_barrier and |
| math_force_eval macros. If FLT_EVAL_METHOD is not 0, force |
| x to float using asm. |
| |
| sysdeps/ieee754/ldbl-128/s_nexttowardf.c | 26 ++++++++++++++++---------- |
| 1 file changed, 16 insertions(+), 10 deletions(-) |
| |
| diff -durN glibc-2.10.1.orig/sysdeps/ieee754/ldbl-128/s_nexttowardf.c glibc-2.10.1/sysdeps/ieee754/ldbl-128/s_nexttowardf.c |
| --- glibc-2.10.1.orig/sysdeps/ieee754/ldbl-128/s_nexttowardf.c 1999-07-14 02:09:42.000000000 +0200 |
| +++ glibc-2.10.1/sysdeps/ieee754/ldbl-128/s_nexttowardf.c 2009-11-13 00:50:06.000000000 +0100 |
| @@ -19,7 +19,8 @@ |
| #endif |
| |
| #include "math.h" |
| -#include "math_private.h" |
| +#include <math_private.h> |
| +#include <float.h> |
| |
| #ifdef __STDC__ |
| float __nexttowardf(float x, long double y) |
| @@ -44,10 +45,12 @@ |
| return x+y; |
| if((long double) x==y) return y; /* x=y, return y */ |
| if(ix==0) { /* x == 0 */ |
| - float x2; |
| + float u; |
| SET_FLOAT_WORD(x,(u_int32_t)((hy>>32)&0x80000000)|1);/* return +-minsub*/ |
| - x2 = x*x; |
| - if(x2==x) return x2; else return x; /* raise underflow flag */ |
| + u = math_opt_barrier (x); |
| + u = u * u; |
| + math_force_eval (u); /* raise underflow flag */ |
| + return x; |
| } |
| if(hx>=0) { /* x > 0 */ |
| if(hy<0||(ix>>23)>(iy>>48)-0x3f80 |
| @@ -67,13 +70,16 @@ |
| } |
| } |
| hy = hx&0x7f800000; |
| - if(hy>=0x7f800000) return x+x; /* overflow */ |
| + if(hy>=0x7f800000) { |
| + x = x+x; /* overflow */ |
| + if (FLT_EVAL_METHOD != 0) |
| + /* Force conversion to float. */ |
| + asm ("" : "+m"(x)); |
| + return x; |
| + } |
| if(hy<0x00800000) { /* underflow */ |
| - float x2 = x*x; |
| - if(x2!=x) { /* raise underflow flag */ |
| - SET_FLOAT_WORD(x2,hx); |
| - return x2; |
| - } |
| + float u = x*x; |
| + math_force_eval (u); /* raise underflow flag */ |
| } |
| SET_FLOAT_WORD(x,hx); |
| return x; |