diff options
author | Andreas Schwab <schwab@suse.de> | 2001-02-16 13:40:22 +0000 |
---|---|---|
committer | Andreas Schwab <schwab@suse.de> | 2001-02-16 13:40:22 +0000 |
commit | a2eb6df0cbd412cb9a82301d9f5f2864bcd83928 (patch) | |
tree | 0222ae8c8b4d2be1dff91357acaf87cc408cce94 | |
parent | 2d0aea11b0637e7ad3c5df6da3395a8248416811 (diff) | |
download | glibc-a2eb6df0cbd412cb9a82301d9f5f2864bcd83928.zip glibc-a2eb6df0cbd412cb9a82301d9f5f2864bcd83928.tar.gz glibc-a2eb6df0cbd412cb9a82301d9f5f2864bcd83928.tar.bz2 |
Correctly handle m68k long double format.
-rw-r--r-- | sysdeps/m68k/fpu/s_fpclassifyl.c | 43 | ||||
-rw-r--r-- | sysdeps/m68k/fpu/s_nextafterl.c | 109 |
2 files changed, 152 insertions, 0 deletions
diff --git a/sysdeps/m68k/fpu/s_fpclassifyl.c b/sysdeps/m68k/fpu/s_fpclassifyl.c new file mode 100644 index 0000000..74aa720 --- /dev/null +++ b/sysdeps/m68k/fpu/s_fpclassifyl.c @@ -0,0 +1,43 @@ +/* Return classification value corresponding to argument. m68k version. + Copyright (C) 1997,2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. + Fixed for m68k by Andreas Schwab <schwab@suse.de>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <math.h> + +#include "math_private.h" + + +int +__fpclassifyl (long double x) +{ + u_int32_t ex, hx, lx; + int retval = FP_NORMAL; + + GET_LDOUBLE_WORDS (ex, hx, lx, x); + ex &= 0x7fff; + if ((ex | hx | lx) == 0) + retval = FP_ZERO; + else if (ex == 0 && (hx & 0x80000000) == 0) + retval = FP_SUBNORMAL; + else if (ex == 0x7fff) + retval = ((hx & 0x7fffffff) | lx) != 0 ? FP_NAN : FP_INFINITE; + + return retval; +} diff --git a/sysdeps/m68k/fpu/s_nextafterl.c b/sysdeps/m68k/fpu/s_nextafterl.c new file mode 100644 index 0000000..70ab5a4 --- /dev/null +++ b/sysdeps/m68k/fpu/s_nextafterl.c @@ -0,0 +1,109 @@ +/* s_nextafterl.c -- long double version of s_nextafter.c. + * Conversion to long double by Ulrich Drepper, + * Cygnus Support, drepper@cygnus.com. + * Fixed for m68k by Andreas Schwab <schwab@suse.de>. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: $"; +#endif + +/* IEEE functions + * nextafterl(x,y) + * return the next machine floating-point number of x in the + * direction toward y. + * Special cases: + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ + long double __nextafterl(long double x, long double y) +#else + long double __nextafterl(x,y) + long double x,y; +#endif +{ + int32_t ix,iy,esx,esy; + u_int32_t hx,hy,lx,ly; + + GET_LDOUBLE_WORDS(esx,hx,lx,x); + GET_LDOUBLE_WORDS(esy,hy,ly,y); + ix = esx&0x7fff; /* |x| */ + iy = esy&0x7fff; /* |y| */ + + if(((ix==0x7fff)&&((hx&0x7fffffff)|lx)!=0) || /* x is nan */ + ((iy==0x7fff)&&((hy&0x7fffffff)|ly)!=0)) /* y is nan */ + return x+y; + if(x==y) return y; /* x=y, return y */ + if((ix|hx|lx)==0) { /* x == 0 */ + SET_LDOUBLE_WORDS(x,esy&0x8000,0,1);/* return +-minsubnormal */ + y = x*x; + if(y==x) return y; else return x; /* raise underflow flag */ + } + if(esx>=0) { /* x > 0 */ + if(esx>esy||((esx==esy) && (hx>hy||((hx==hy)&&(lx>ly))))) { + /* x > y, x -= ulp */ + if(lx==0) { + if (ix != 0 && hx == 0x80000000) hx = 0; + if (hx==0) esx -= 1; + hx -= 1; + } + lx -= 1; + } else { /* x < y, x += ulp */ + lx += 1; + if(lx==0) { + hx += 1; + if (hx==0) { + hx = 0x80000000; + esx += 1; + } + } + } + } else { /* x < 0 */ + if(esy>=0||esx>esy||((esx==esy) && (hx>hy||((hx==hy)&&(lx>ly))))){ + /* x < y, x -= ulp */ + if(lx==0) { + if (ix != 0 && hx == 0x80000000) hx = 0; + if (hx==0) esx -= 1; + hx -= 1; + } + lx -= 1; + } else { /* x > y, x += ulp */ + lx += 1; + if(lx==0) { + hx += 1; + if (hx==0) { + hx = 0x80000000; + esx += 1; + } + } + } + } + esy = esx&0x7fff; + if(esy==0x7fff) return x+x; /* overflow */ + if(esy==0 && (hx & 0x80000000) == 0) { /* underflow */ + y = x*x; + if(y!=x) { /* raise underflow flag */ + SET_LDOUBLE_WORDS(y,esx,hx,lx); + return y; + } + } + SET_LDOUBLE_WORDS(x,esx,hx,lx); + return x; +} +weak_alias (__nextafterl, nextafterl) +strong_alias (__nextafterl, __nexttowardl) +weak_alias (__nextafterl, nexttowardl) |