commit long double SoC code from Stathis Kamperis

This commit is contained in:
christos 2010-09-15 16:12:05 +00:00
parent e2a86dd3c7
commit 98b923b685
4 changed files with 277 additions and 0 deletions

View File

@ -0,0 +1,49 @@
/* $NetBSD: s_copysignl.c,v 1.1 2010/09/15 16:12:05 christos Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: s_copysignl.c,v 1.1 2010/09/15 16:12:05 christos Exp $");
#include <math.h>
#include <machine/ieee.h>
/*
* copysignl(long double x, long double y)
* This function returns a value with the magnitude of x and the sign of y.
*/
long double
copysignl(long double x, long double y)
{
union ieee_ext_u ux, uy;
ux.extu_ld = x;
uy.extu_ld = y;
ux.extu_ext.ext_sign = uy.extu_ext.ext_sign;
return (ux.extu_ld);
}

47
lib/libm/src/s_fabsl.c Normal file
View File

@ -0,0 +1,47 @@
/* $NetBSD: s_fabsl.c,v 1.1 2010/09/15 16:12:05 christos Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: s_fabsl.c,v 1.1 2010/09/15 16:12:05 christos Exp $");
#include <math.h>
#include <machine/ieee.h>
/*
* fabsl(long double x)
* This function returns the absolute value of its argumetn x, |x|.
*/
long double
fabsl(long double x)
{
union ieee_ext_u ux;
ux.extu_ld = x;
ux.extu_ext.ext_sign = 0;
return (ux.extu_ld);
}

View File

@ -0,0 +1,92 @@
/* $NetBSD: s_nextafterl.c,v 1.1 2010/09/15 16:12:05 christos Exp $ */
/* @(#)s_nextafter.c 5.1 93/09/24 */
/*
* ====================================================
* 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.
* ====================================================
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: s_nextafterl.c,v 1.1 2010/09/15 16:12:05 christos Exp $");
#include <float.h>
#include <math.h>
#include <machine/ieee.h>
#if LDBL_MAX_EXP != 0x4000
#error "Unsupported long double format"
#endif
/*
* IEEE functions
* nextafterl(x,y)
* return the next machine floating-point number of x in the
* direction toward y.
* Special cases:
* If x == y, y shall be returned
* If x or y is NaN, a NaN shall be returned
*/
long double
nextafterl(long double x, long double y)
{
volatile long double t;
union ieee_ext_u ux, uy;
ux.extu_ld = x;
uy.extu_ld = y;
if ((ux.extu_exp == EXT_EXP_NAN &&
((ux.extu_frach &~ LDBL_NBIT)|ux.extu_fracl) != 0) ||
(uy.extu_exp == EXT_EXP_NAN &&
((uy.extu_frach &~ LDBL_NBIT)|uy.extu_fracl) != 0))
return x+y; /* x or y is nan */
if (x == y) return y; /* x=y, return y */
if (x == 0.0) {
ux.extu_frach = 0; /* return +-minsubnormal */
ux.extu_fracl = 1;
ux.extu_sign = uy.extu_sign;
t = ux.extu_ld * ux.extu_ld;
if (t == ux.extu_ld)
return t;
else
return ux.extu_ld; /* raise underflow flag */
}
if ((x>0.0) ^ (x<y)) { /* x -= ulp */
if (ux.extu_fracl == 0) {
if ((ux.extu_frach & ~LDBL_NBIT) == 0)
ux.extu_exp -= 1;
ux.extu_frach = (ux.extu_frach - 1) |
(ux.extu_frach & LDBL_NBIT);
}
ux.extu_fracl -= 1;
} else { /* x += ulp */
ux.extu_fracl += 1;
if (ux.extu_fracl == 0) {
ux.extu_frach = (ux.extu_frach + 1) |
(ux.extu_frach & LDBL_NBIT);
if ((ux.extu_frach & ~LDBL_NBIT) == 0)
ux.extu_exp += 1;
}
}
if (ux.extu_exp == EXT_EXP_INF)
return x+x; /* overflow */
if (ux.extu_exp == 0) { /* underflow */
mask_nbit_l(ux);
t = ux.extu_ld * ux.extu_ld;
if (t != ux.extu_ld) /* raise underflow flag */
return ux.extu_ld;
}
return ux.extu_ld;
}

View File

@ -0,0 +1,89 @@
/* $NetBSD: s_nexttoward.c,v 1.1 2010/09/15 16:12:05 christos Exp $ */
/* @(#)s_nextafter.c 5.1 93/09/24 */
/*
* ====================================================
* 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.
* ====================================================
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: s_nexttoward.c,v 1.1 2010/09/15 16:12:05 christos Exp $");
/*
* We assume that a long double has a 15-bit exponent. On systems
* where long double is the same as double, nexttoward() is an alias
* for nextafter(), so we don't use this routine.
*/
#include <float.h>
#include <machine/ieee.h>
#include "math.h"
#include "math_private.h"
#if LDBL_MAX_EXP != 0x4000
#error "Unsupported long double format"
#endif
/*
* The nexttoward() function is equivalent to nextafter() function,
* except that the second parameter shall have type long double and
* the functions shall return y converted to the type of the function
* if x equals y.
*
* Special cases: XXX
*/
double
nexttoward(double x, long double y)
{
union ieee_ext_u uy;
volatile double t;
int32_t hx, ix;
uint32_t lx;
EXTRACT_WORDS(hx, lx, x);
ix = hx & 0x7fffffff; /* |x| */
uy.extu_ld = y;
if (((ix >= 0x7ff00000) && ((ix - 0x7ff00000) | lx) != 0) ||
(uy.extu_exp == 0x7fff &&
((uy.extu_frach & ~LDBL_NBIT) | uy.extu_fracl) != 0))
return x+y; /* x or y is nan */
if (x == y)
return (double)y; /* x=y, return y */
if (x == 0.0) {
INSERT_WORDS(x, uy.extu_sign<<31, 1); /* return +-minsubnormal */
t = x*x;
if (t == x)
return t;
else
return x; /* raise underflow flag */
}
if ((hx > 0.0) ^ (x < y)) { /* x -= ulp */
if (lx == 0) hx -= 1;
lx -= 1;
} else { /* x += ulp */
lx += 1;
if (lx == 0) hx += 1;
}
ix = hx & 0x7ff00000;
if (ix >= 0x7ff00000) return x+x; /* overflow */
if (ix < 0x00100000) { /* underflow */
t = x*x;
if (t != x) { /* raise underflow flag */
INSERT_WORDS(y, hx, lx);
return y;
}
}
INSERT_WORDS(x, hx, lx);
return x;
}