* sysdeps/alpha/fpu/s_ceil.c: Rewrite without branches.

* sysdeps/alpha/fpu/s_ceilf.c: Likewise.
	* sysdeps/alpha/fpu/s_floor.c: Likewise.
	* sysdeps/alpha/fpu/s_floorf.c: Likewise.
	* sysdeps/alpha/fpu/s_rint.c: Likewise.
	* sysdeps/alpha/fpu/s_rintf.c: Likewise.

	* sysdeps/alpha/fpu/s_fmax.S: New file.
	* sysdeps/alpha/fpu/s_fmaxf.S: New file.
	* sysdeps/alpha/fpu/s_fmin.S: New file.
	* sysdeps/alpha/fpu/s_fminf.S: New file.
	* sysdeps/alpha/fpu/s_isnan.c: New file.
	* sysdeps/alpha/fpu/s_isnanf.c: New file.
	* sysdeps/alpha/fpu/s_llrint.c: New file.
	* sysdeps/alpha/fpu/s_llrintf.c: New file.
	* sysdeps/alpha/fpu/s_lrint.c: New file.
	* sysdeps/alpha/fpu/s_lrintf.c: New file.
	* sysdeps/alpha/fpu/s_nearbyint.c: New file.
	* sysdeps/alpha/fpu/s_nearbyintf.c: New file.

	* sysdeps/alpha/fpu/bits/mathinline.h (__floorf, __floor): Remove.
	(__fdimf, fdimf, __fdim, fdim): Remove.
	(__signbitf, __signbit, __signbitl): Use gcc builtin if available.
	(__isnanf, __isnan, __isnanl): New.
This commit is contained in:
Richard Henderson 2007-03-14 17:44:14 +00:00
parent 9ea0d86579
commit bebc49030c
19 changed files with 450 additions and 194 deletions

View File

@ -1,5 +1,6 @@
/* Inline math functions for Alpha.
Copyright (C) 1996, 1997, 1999-2001, 2004 Free Software Foundation, Inc.
Copyright (C) 1996, 1997, 1999-2001, 2004, 2007
Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by David Mosberger-Tang.
@ -83,111 +84,64 @@ __inline_fabs (fabs, double)
# undef __inline_fabs
#endif
/* 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. */
__MATH_INLINE float
__NTH (__floorf (float __x))
{
/* Check not zero since floor(-0) == -0. */
if (__x != 0 && 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;
__asm ("cvtst/s %3,%2\n\t"
#ifdef _IEEE_FP_INEXACT
"cvttq/svim %2,%1\n\t"
#else
"cvttq/svm %2,%1\n\t"
#endif
"cvtqt/m %1,%0\n\t"
: "=f"(__x), "=&f"(__tmp1), "=&f"(__tmp2)
: "f"(__x));
}
return __x;
}
__MATH_INLINE double
__NTH (__floor (double __x))
{
if (__x != 0 && fabs (__x) < 9007199254740992.0) /* 1 << DBL_MANT_DIG */
{
double __tmp1;
__asm (
#ifdef _IEEE_FP_INEXACT
"cvttq/svim %2,%1\n\t"
#else
"cvttq/svm %2,%1\n\t"
#endif
"cvtqt/m %1,%0\n\t"
: "=f"(__x), "=&f"(__tmp1)
: "f"(__x));
}
return __x;
}
__MATH_INLINE float __NTH (floorf (float __x)) { return __floorf(__x); }
__MATH_INLINE double __NTH (floor (double __x)) { return __floor(__x); }
#ifdef __USE_ISOC99
__MATH_INLINE float
__NTH (__fdimf (float __x, float __y))
{
return __x <= __y ? 0.0f : __x - __y;
}
__MATH_INLINE float
__NTH (fdimf (float __x, float __y))
{
return __x <= __y ? 0.0f : __x - __y;
}
__MATH_INLINE double
__NTH (__fdim (double __x, double __y))
{
return __x <= __y ? 0.0 : __x - __y;
}
__MATH_INLINE double
__NTH (fdim (double __x, double __y))
{
return __x <= __y ? 0.0 : __x - __y;
}
/* Test for negative number. Used in the signbit() macro. */
__MATH_INLINE int
__NTH (__signbitf (float __x))
{
#if !__GNUC_PREREQ (4, 0)
__extension__ union { float __f; int __i; } __u = { __f: __x };
return __u.__i < 0;
#else
return __builtin_signbitf (__x);
#endif
}
__MATH_INLINE int
__NTH (__signbit (double __x))
{
#if !__GNUC_PREREQ (4, 0)
__extension__ union { double __d; long __i; } __u = { __d: __x };
return __u.__i < 0;
#else
return __builtin_signbit (__x);
#endif
}
__MATH_INLINE int
__NTH (__signbitl (long double __x))
{
#if !__GNUC_PREREQ (4, 0)
__extension__ union {
long double __d;
long __i[sizeof(long double)/sizeof(long)];
} __u = { __d: __x };
return __u.__i[sizeof(long double)/sizeof(long) - 1] < 0;
#else
return __builtin_signbitl (__x);
#endif
}
/* Test for NaN. Used in the isnan() macro. */
__MATH_INLINE int
__NTH (__isnanf (float __x))
{
return isunordered (__x, __x);
}
__MATH_INLINE int
__NTH (__isnan (double __x))
{
return isunordered (__x, __x);
}
__MATH_INLINE int
__NTH (__isnanl (long double __x))
{
return isunordered (__x, __x);
}
#endif /* C99 */
#endif /* __NO_MATH_INLINES */

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1998, 2000, 2006 Free Software Foundation, Inc.
/* Copyright (C) 1998, 2000, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Richard Henderson.
@ -27,25 +27,20 @@
double
__ceil (double x)
{
if (isless (fabs (x), 9007199254740992.0)) /* 1 << DBL_MANT_DIG */
{
double tmp1, new_x;
new_x = -x;
__asm (
double two52 = copysign (0x1.0p52, x);
double r, tmp;
__asm (
#ifdef _IEEE_FP_INEXACT
"cvttq/svim %2,%1\n\t"
"addt/suim %2, %3, %1\n\tsubt/suim %1, %3, %0"
#else
"cvttq/svm %2,%1\n\t"
"addt/sum %2, %3, %1\n\tsubt/sum %1, %3, %0"
#endif
"cvtqt/m %1,%0\n\t"
: "=f"(new_x), "=&f"(tmp1)
: "f"(new_x));
: "=&f"(r), "=&f"(tmp)
: "f"(-x), "f"(-two52));
/* Fix up the negation we did above, as well as handling -0 properly. */
x = copysign(new_x, x);
}
return x;
/* Fix up the negation we did above, as well as handling -0 properly. */
return copysign (r, x);
}
weak_alias (__ceil, ceil)

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1998, 2000 Free Software Foundation, Inc.
/* Copyright (C) 1998, 2000, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Richard Henderson.
@ -26,30 +26,20 @@
float
__ceilf (float x)
{
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"
float two23 = copysignf (0x1.0p23, x);
float r, tmp;
__asm (
#ifdef _IEEE_FP_INEXACT
"cvttq/svim %2,%1\n\t"
"adds/suim %2, %3, %1\n\tsubs/suim %1, %3, %0"
#else
"cvttq/svm %2,%1\n\t"
"adds/sum %2, %3, %1\n\tsubs/sum %1, %3, %0"
#endif
"cvtqt/m %1,%0\n\t"
: "=f"(new_x), "=&f"(tmp1), "=&f"(tmp2)
: "f"(new_x));
: "=&f"(r), "=&f"(tmp)
: "f"(-x), "f"(-two23));
/* Fix up the negation we did above, as well as handling -0 properly. */
x = copysignf(new_x, x);
}
return x;
/* Fix up the negation we did above, as well as handling -0 properly. */
return copysignf (r, x);
}
weak_alias (__ceilf, ceilf)

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1998, 1999, 2000, 2006 Free Software Foundation, Inc.
/* Copyright (C) 1998, 1999, 2000, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Richard Henderson.
@ -28,25 +28,21 @@
double
__floor (double x)
{
if (isless (fabs (x), 9007199254740992.0)) /* 1 << DBL_MANT_DIG */
{
double tmp1, new_x;
__asm (
double two52 = copysign (0x1.0p52, x);
double r, tmp;
__asm (
#ifdef _IEEE_FP_INEXACT
"cvttq/svim %2,%1\n\t"
"addt/suim %2, %3, %1\n\tsubt/suim %1, %3, %0"
#else
"cvttq/svm %2,%1\n\t"
"addt/sum %2, %3, %1\n\tsubt/sum %1, %3, %0"
#endif
"cvtqt/m %1,%0\n\t"
: "=f"(new_x), "=&f"(tmp1)
: "f"(x));
: "=&f"(r), "=&f"(tmp)
: "f"(x), "f"(two52));
/* floor(-0) == -0, and in general we'll always have the same
sign as our input. */
x = copysign(new_x, x);
}
return x;
/* floor(-0) == -0, and in general we'll always have the same
sign as our input. */
return copysign (r, x);
}
weak_alias (__floor, floor)

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
/* Copyright (C) 1998, 1999, 2000, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Richard Henderson.
@ -27,30 +27,21 @@
float
__floorf (float x)
{
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"
float two23 = copysignf (0x1.0p23, x);
float r, tmp;
__asm (
#ifdef _IEEE_FP_INEXACT
"cvttq/svim %2,%1\n\t"
"adds/suim %2, %3, %1\n\tsubs/suim %1, %3, %0"
#else
"cvttq/svm %2,%1\n\t"
"adds/sum %2, %3, %1\n\tsubs/sum %1, %3, %0"
#endif
"cvtqt/m %1,%0\n\t"
: "=f"(new_x), "=&f"(tmp1), "=&f"(tmp2)
: "f"(x));
: "=&f"(r), "=&f"(tmp)
: "f"(x), "f"(two23));
/* floor(-0) == -0, and in general we'll always have the same
sign as our input. */
x = copysignf(new_x, x);
}
return x;
/* floor(-0) == -0, and in general we'll always have the same
sign as our input. */
return copysignf (r, x);
}
weak_alias (__floorf, floorf)

View File

@ -0,0 +1,58 @@
/* Copyright (C) 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Richard Henderson.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <sysdep.h>
#include <math_ldbl_opt.h>
.set noat
.set noreorder
.text
ENTRY (__fmax)
.prologue 0
cmptun/su $f16, $f16, $f10
cmptun/su $f17, $f17, $f11
fmov $f17, $f0
unop
trapb
fbne $f10, $ret
fmov $f16, $f0
fbne $f11, $ret
cmptlt/su $f16, $f17, $f11
trapb
fcmovne $f11, $f17, $f0
$ret: ret
END (__fmax)
/* Given the in-register format of single-precision, this works there too. */
strong_alias (__fmax, __fmaxf)
weak_alias (__fmaxf, fmaxf)
weak_alias (__fmax, fmax)
#ifdef NO_LONG_DOUBLE
strong_alias (__fmax, __fmaxl)
weak_alias (__fmaxl, fmaxl)
#endif
#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
compat_symbol (libm, __fmax, fmaxl, GLIBC_2_0);
#endif

View File

@ -0,0 +1 @@
/* __fmaxf is in s_fmax.c */

View File

@ -0,0 +1,58 @@
/* Copyright (C) 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Richard Henderson.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <sysdep.h>
#include <math_ldbl_opt.h>
.set noat
.set noreorder
.text
ENTRY (__fmin)
.prologue 0
cmptun/su $f16, $f16, $f10
cmptun/su $f17, $f17, $f11
fmov $f17, $f0
unop
trapb
fbne $f10, $ret
fmov $f16, $f0
fbne $f11, $ret
cmptlt/su $f17, $f16, $f11
trapb
fcmovne $f11, $f17, $f0
$ret: ret
END (__fmin)
/* Given the in-register format of single-precision, this works there too. */
strong_alias (__fmin, __fminf)
weak_alias (__fminf, fminf)
weak_alias (__fmin, fmin)
#ifdef NO_LONG_DOUBLE
strong_alias (__fmin, __fminl)
weak_alias (__fminl, fminl)
#endif
#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
compat_symbol (libm, __fmin, fminl, GLIBC_2_0);
#endif

View File

@ -0,0 +1 @@
/* __fminf is in s_fmin.c */

View File

@ -0,0 +1,58 @@
/* Return 1 if argument is a NaN, else 0.
Copyright (C) 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
/* Ugly kludge to avoid declarations. */
#define __isnanf not___isnanf
#define isnanf not_isnanf
#define __GI___isnanf not__GI___isnanf
#include <math.h>
#include <math_ldbl_opt.h>
#undef __isnanf
#undef isnanf
#undef __GI___isnanf
/* The hidden_proto in include/math.h was obscured by the macro hackery. */
__typeof (__isnan) __isnanf;
hidden_proto (__isnanf)
int
__isnan (double x)
{
return isunordered (x, x);
}
hidden_def (__isnan)
weak_alias (__isnan, isnan)
/* It turns out that the 'double' version will also always work for
single-precision. */
strong_alias (__isnan, __isnanf)
hidden_def (__isnanf)
weak_alias (__isnanf, isnanf)
#ifdef NO_LONG_DOUBLE
strong_alias (__isnan, __isnanl)
weak_alias (__isnan, isnanl)
#endif
#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
compat_symbol (libm, __isnan, isnanl, GLIBC_2_0);
#endif

View File

@ -0,0 +1 @@
/* In s_isnan.c */

View File

@ -0,0 +1 @@
/* In s_lrint.c */

View File

@ -0,0 +1 @@
/* In s_lrintf.c */

View File

@ -0,0 +1,48 @@
/* Copyright (C) 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#define __llrint not___llrint
#define llrint not_llrint
#include <math.h>
#include <math_ldbl_opt.h>
#undef __llrint
#undef llrint
long int
__lrint (double x)
{
long ret;
__asm ("cvttq/svd %1,%0" : "=&f"(ret) : "f"(x));
return ret;
}
strong_alias (__lrint, __llrint)
weak_alias (__lrint, lrint)
weak_alias (__llrint, llrint)
#ifdef NO_LONG_DOUBLE
strong_alias (__lrint, __lrintl)
strong_alias (__lrint, __llrintl)
weak_alias (__lrintl, lrintl)
weak_alias (__llrintl, llrintl)
#endif
#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
compat_symbol (libm, __lrint, lrintl, GLIBC_2_0);
compat_symbol (libm, __llrint, llrintl, GLIBC_2_0);
#endif

View File

@ -0,0 +1,39 @@
/* Copyright (C) 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#define __llrintf not___llrintf
#define llrintf not_llrintf
#include <math.h>
#undef __llrintf
#undef llrintf
long int
__lrintf (float x)
{
double tmp;
long ret;
__asm ("cvtst/s %2,%1\n\tcvttq/svd %1,%0"
: "=&f"(ret), "=&f"(tmp) : "f"(x));
return ret;
}
strong_alias (__lrintf, __llrintf)
weak_alias (__lrintf, lrintf)
weak_alias (__llrintf, llrintf)

View File

@ -0,0 +1,48 @@
/* Copyright (C) 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Richard Henderson.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <math.h>
#include <math_ldbl_opt.h>
#ifdef _IEEE_FP_INEXACT
#error "Don't compile with -mieee-with-inexact"
#endif
double
__nearbyint (double x)
{
double two52 = copysign (0x1.0p52, x);
double r;
r = x + two52;
r = r - two52;
/* nearbyint(-0.1) == -0, and in general we'll always have the same sign
as our input. */
return copysign (r, x);
}
weak_alias (__nearbyint, nearbyint)
#ifdef NO_LONG_DOUBLE
strong_alias (__nearbyint, __nearbyintl)
weak_alias (__nearbyint, nearbyintl)
#endif
#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
compat_symbol (libm, __nearbyint, nearbyintl, GLIBC_2_0);
#endif

View File

@ -0,0 +1,40 @@
/* Copyright (C) 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Richard Henderson.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <math.h>
#ifdef _IEEE_FP_INEXACT
#error "Don't compile with -mieee-with-inexact"
#endif
float
__nearbyintf (float x)
{
float two23 = copysignf (0x1.0p23, x);
float r;
r = x + two23;
r = r - two23;
/* nearbyint(-0.1) == -0, and in general we'll always have the same sign
as our input. */
return copysign (r, x);
}
weak_alias (__nearbyintf, nearbyintf)

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2000, 2006 Free Software Foundation, Inc.
/* Copyright (C) 2000, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Richard Henderson.
@ -24,24 +24,15 @@
double
__rint (double x)
{
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));
double two52 = copysign (0x1.0p52, x);
double r;
r = x + two52;
r = r - two52;
/* rint(-0.1) == -0, and in general we'll always have the same
sign as our input. */
x = copysign(new_x, x);
}
return x;
/* rint(-0.1) == -0, and in general we'll always have the same sign
as our input. */
return copysign (r, x);
}
weak_alias (__rint, rint)

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2000 Free Software Foundation, Inc.
/* Copyright (C) 2000, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Richard Henderson.
@ -23,30 +23,15 @@
float
__rintf (float x)
{
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 two23 = copysignf (0x1.0p23, x);
float r;
float tmp1, tmp2, new_x;
r = x + two23;
r = r - two23;
__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;
/* rint(-0.1) == -0, and in general we'll always have the same sign
as our input. */
return copysign (r, x);
}
weak_alias (__rintf, rintf)