diff options
author | Piotr Jasiukajtis <estibi@me.com> | 2014-02-04 20:31:57 +0100 |
---|---|---|
committer | Dan McDonald <danmcd@omniti.com> | 2014-10-17 18:00:52 -0400 |
commit | 25c28e83beb90e7c80452a7c818c5e6f73a07dc8 (patch) | |
tree | 95cb102e7fb37f52d4b3ec3e44508f352a335ee5 /usr/src/lib/libm/common/R | |
parent | 4e6070e87069f63bef94d8e79c2fc3cab2c1ab6b (diff) | |
download | illumos-gate-25c28e83beb90e7c80452a7c818c5e6f73a07dc8.tar.gz |
693 Opensource replacement of sunwlibm
Reviewed by: Igor Kozhukhov ikozhukhov@gmail.com
Reviewed by: Keith M Wesolowski <keith.wesolowski@joyent.com>
Reviewed by: Richard Lowe <richlowe@richlowe.net>
Approved by: Dan McDonald <danmcd@omniti.com>
Diffstat (limited to 'usr/src/lib/libm/common/R')
53 files changed, 5563 insertions, 0 deletions
diff --git a/usr/src/lib/libm/common/R/_TBL_r_atan_.c b/usr/src/lib/libm/common/R/_TBL_r_atan_.c new file mode 100644 index 0000000000..c5caa798e1 --- /dev/null +++ b/usr/src/lib/libm/common/R/_TBL_r_atan_.c @@ -0,0 +1,75 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * Table of constants for r_atan_(). + * By K.C. Ng, March 9, 1989 + */ + +#include "libm.h" + +const float _TBL_r_atan_hi[] = { + 4.636476040e-01, 4.883339405e-01, 5.123894811e-01, 5.358112454e-01, + 5.585992932e-01, 5.807563663e-01, 6.022873521e-01, 6.231993437e-01, + 6.435011029e-01, 6.632030010e-01, 6.823165417e-01, 7.008544207e-01, + 7.188299894e-01, 7.362574339e-01, 7.531512976e-01, 7.695264816e-01, + 7.853981853e-01, 8.156919479e-01, 8.441540003e-01, 8.709034324e-01, + 8.960554004e-01, 9.197195768e-01, 9.420000315e-01, 9.629943371e-01, + 9.827937484e-01, 1.001483083e+00, 1.019141316e+00, 1.035841227e+00, + 1.051650167e+00, 1.066630363e+00, 1.080839038e+00, 1.094328880e+00, + 1.107148767e+00, 1.130953789e+00, 1.152572036e+00, 1.172273874e+00, + 1.190289974e+00, 1.206817389e+00, 1.222025275e+00, 1.236059427e+00, + 1.249045730e+00, 1.261093378e+00, 1.272297382e+00, 1.282740831e+00, + 1.292496681e+00, 1.301628828e+00, 1.310193896e+00, 1.318242073e+00, + 1.325817704e+00, 1.339705706e+00, 1.352127433e+00, 1.363300085e+00, + 1.373400807e+00, 1.382574797e+00, 1.390942812e+00, 1.398605466e+00, + 1.405647635e+00, 1.412141085e+00, 1.418146968e+00, 1.423717976e+00, + 1.428899288e+00, 1.433730125e+00, 1.438244820e+00, 1.442473054e+00, + 1.446441293e+00, +}; + +const float _TBL_r_atan_lo[] = { + +5.012158688e-09, +1.055042365e-08, -2.075691974e-08, -7.480973174e-09, + +2.211159789e-08, -1.268522887e-08, -5.950149262e-09, -1.374726910e-08, + +5.868937336e-09, -8.316245470e-09, +1.320299514e-08, -1.277747597e-08, + +1.018833551e-08, -4.909868068e-09, -1.660708016e-08, -1.222759671e-09, + -2.185569414e-08, -2.462078896e-08, -1.416911655e-08, +2.470642002e-08, + -1.580020736e-08, +2.851478520e-08, +8.908211058e-09, -6.400973085e-09, + -2.513142405e-08, +5.292293181e-08, +2.785247055e-08, +2.643104224e-08, + +4.603683834e-08, +1.851388043e-09, -3.735403453e-08, +2.701113111e-08, + -4.872354964e-08, -4.477816518e-08, -3.857382325e-08, +6.845639611e-09, + -2.453011483e-08, -1.824929363e-08, +4.798058129e-08, +6.221672777e-08, + +4.276110843e-08, +4.185424007e-09, +1.285398099e-08, +4.836914869e-08, + -1.342359379e-08, +5.960489879e-09, +3.875391386e-08, -2.204224536e-08, + -4.053271141e-08, -4.604370218e-08, -5.190222652e-08, +1.529194549e-08, + -4.043566193e-08, +2.481348993e-08, +1.503647518e-08, +4.638297924e-08, + +1.392036975e-08, -2.006252586e-08, +3.051175312e-08, -4.209960824e-09, + -1.598675681e-08, +2.705746205e-08, -2.514289044e-08, +4.517691110e-08, + +3.948537852e-08, +}; diff --git a/usr/src/lib/libm/common/R/__cosf.c b/usr/src/lib/libm/common/R/__cosf.c new file mode 100644 index 0000000000..c17cc00b7f --- /dev/null +++ b/usr/src/lib/libm/common/R/__cosf.c @@ -0,0 +1,86 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include "libm.h" + +/* INDENT OFF */ +/* + * float __k_cos(double x); + * kernel (float) cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164 + * Input x is in double and assumed to be bounded by ~pi/4 in magnitude. + * + * Method: Let z = x * x, then + * C(x) = (C0 + C1*z + C2*z*z) * (C3 + C4*z + z*z) + * where + * C0 = 1.09349482127188401868272000389539985058873853699e-0003 + * C1 = -5.03324285989964979398034700054920226866107675091e-0004 + * C2 = 2.43792880266971107750418061559602239831538067410e-0005 + * C3 = 9.14499072605666582228127405245558035523741471271e+0002 + * C4 = -3.63151270591815439197122504991683846785293207730e+0001 + * + * The remez error is bound by |cos(x) - C(x)| < 2**(-34.2) + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ +/* INDENT ON */ + +static const double q[] = { +/* C0 = */ 1.09349482127188401868272000389539985058873853699e-0003, +/* C1 = */ -5.03324285989964979398034700054920226866107675091e-0004, +/* C2 = */ 2.43792880266971107750418061559602239831538067410e-0005, +/* C3 = */ 9.14499072605666582228127405245558035523741471271e+0002, +/* C4 = */ -3.63151270591815439197122504991683846785293207730e+0001, +}; + +#define C0 q[0] +#define C1 q[1] +#define C2 q[2] +#define C3 q[3] +#define C4 q[4] + +float +__k_cosf(double x) { + float ft; + double z; + int hx; + + hx = ((int *) &x)[HIWORD]; /* hx = leading x */ + if ((hx & ~0x80000000) < 0x3f100000) { /* |x| < 2**-14 */ + ft = (float) 1; + if (((int) x) == 0) /* raise inexact if x != 0 */ + return (ft); + } + z = x * x; + ft = (float) (((C0 + z * C1) + (z * z) * C2) * (C3 + z * (C4 + z))); + return (ft); +} diff --git a/usr/src/lib/libm/common/R/__sincosf.c b/usr/src/lib/libm/common/R/__sincosf.c new file mode 100644 index 0000000000..89c12eeab9 --- /dev/null +++ b/usr/src/lib/libm/common/R/__sincosf.c @@ -0,0 +1,101 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include "libm.h" + +/* INDENT OFF */ +/* + * void __k_sincosf(double x, float *s, float *c); + * kernel (float) sincos function on [-pi/4, pi/4], pi/4 ~ 0.785398164 + * Input x is in double and assumed to be bounded by ~pi/4 in magnitude. + * + * Method: Let z = x * x, then + * S(x) = x(S0 + S1*z)(S2 + S3*z + z*z) + * C(x) = (C0 + C1*z + C2*z*z) * (C3 + C4*z + z*z) + * where + * S0 = 1.85735322054308378716204874632872525989806770558e-0003 + * S1 = -1.95035094218403635082921458859320791358115801259e-0004 + * S2 = 5.38400550766074785970952495168558701485841707252e+0002 + * S3 = -3.31975110777873728964197739157371509422022905947e+0001 + * C0 = 1.09349482127188401868272000389539985058873853699e-0003 + * C1 = -5.03324285989964979398034700054920226866107675091e-0004 + * C2 = 2.43792880266971107750418061559602239831538067410e-0005 + * C3 = 9.14499072605666582228127405245558035523741471271e+0002 + * C4 = -3.63151270591815439197122504991683846785293207730e+0001 + * + * The remez error in S is bound by |(sin(x) - S(x))/x| < 2**(-28.2) + * The remez error in C is bound by |cos(x) - C(x)| < 2**(-34.2) + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ +/* INDENT ON */ + +static const double q[] = { +/* S0 = */ 1.85735322054308378716204874632872525989806770558e-0003, +/* S1 = */ -1.95035094218403635082921458859320791358115801259e-0004, +/* S2 = */ 5.38400550766074785970952495168558701485841707252e+0002, +/* S3 = */ -3.31975110777873728964197739157371509422022905947e+0001, +/* C0 = */ 1.09349482127188401868272000389539985058873853699e-0003, +/* C1 = */ -5.03324285989964979398034700054920226866107675091e-0004, +/* C2 = */ 2.43792880266971107750418061559602239831538067410e-0005, +/* C3 = */ 9.14499072605666582228127405245558035523741471271e+0002, +/* C4 = */ -3.63151270591815439197122504991683846785293207730e+0001, +}; + + +#define S0 q[0] +#define S1 q[1] +#define S2 q[2] +#define S3 q[3] +#define C0 q[4] +#define C1 q[5] +#define C2 q[6] +#define C3 q[7] +#define C4 q[8] + +void +__k_sincosf(double x, float *s, float *c) { + double z; + int hx; + + hx = ((int *) &x)[HIWORD]; /* hx = leading x */ + /* small argument */ + if ((hx & ~0x80000000) < 0x3f100000) { /* if |x| < 2**-14 */ + *s = (float) x; *c = (float) 1; + if ((int) x == 0) /* raise inexact if x != 0 */ + return; + } + z = x * x; + *s = (float) ((x * (S0 + z * S1)) * (S2 + z * (S3 + z))); + *c = (float) (((C0 + z * C1) + (z * z) * C2) * (C3 + z * (C4 + z))); +} diff --git a/usr/src/lib/libm/common/R/__sinf.c b/usr/src/lib/libm/common/R/__sinf.c new file mode 100644 index 0000000000..381ebb9512 --- /dev/null +++ b/usr/src/lib/libm/common/R/__sinf.c @@ -0,0 +1,83 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include "libm.h" + +/* INDENT OFF */ +/* + * float __k_sin(double x); + * kernel (float) sin function on [-pi/4, pi/4], pi/4 ~ 0.785398164 + * Input x is in double and assumed to be bounded by ~pi/4 in magnitude. + * + * Method: Let z = x * x, then + * S(x) = x(S0 + S1*z)(S2 + S3*z + z*z) + * where + * S0 = 1.85735322054308378716204874632872525989806770558e-0003, + * S1 = -1.95035094218403635082921458859320791358115801259e-0004, + * S2 = 5.38400550766074785970952495168558701485841707252e+0002, + * S3 = -3.31975110777873728964197739157371509422022905947e+0001, + * + * The remez error is bound by |(sin(x) - S(x))/x| < 2**(-28.2) + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ +/* INDENT ON */ + +static const double q[] = { +/* S0 = */ 1.85735322054308378716204874632872525989806770558e-0003, +/* S1 = */ -1.95035094218403635082921458859320791358115801259e-0004, +/* S2 = */ 5.38400550766074785970952495168558701485841707252e+0002, +/* S3 = */ -3.31975110777873728964197739157371509422022905947e+0001, +}; + +#define S0 q[0] +#define S1 q[1] +#define S2 q[2] +#define S3 q[3] + +float +__k_sinf(double x) { + float ft; + double z; + int hx; + + hx = ((int *) &x)[HIWORD]; /* hx = leading x */ + if ((hx & ~0x80000000) < 0x3f100000) { /* if |x| < 2**-14 */ + ft = (float) x; + if ((int) x == 0) /* raise inexact if x != 0 */ + return (ft); + } + z = x * x; + ft = (float) ((x * (S0 + z * S1)) * (S2 + z * (S3 + z))); + return (ft); +} diff --git a/usr/src/lib/libm/common/R/__tanf.c b/usr/src/lib/libm/common/R/__tanf.c new file mode 100644 index 0000000000..e42ec914e0 --- /dev/null +++ b/usr/src/lib/libm/common/R/__tanf.c @@ -0,0 +1,96 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include "libm.h" + +/* INDENT OFF */ +/* + * float __k_tan(double x); + * kernel (float) tan function on [-pi/4, pi/4], pi/4 ~ 0.785398164 + * Input x is in double and assumed to be bounded by ~pi/4 in magnitude. + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ + +static const double q[] = { +/* one */ 1.0, +/* P0 */ 4.46066928428959230679140546271810308098793029785e-0003, +/* P1 */ 4.92165316309189027066395283327437937259674072266e+0000, +/* P2 */ -7.11410648161473480044492134766187518835067749023e-0001, +/* P3 */ 4.08549808374053391446523164631798863410949707031e+0000, +/* P4 */ 2.50411070398050927821032018982805311679840087891e+0000, +/* P5 */ 1.11492064560251158411574579076841473579406738281e+0001, +/* P6 */ -1.50565540968422650891511693771462887525558471680e+0000, +/* P7 */ -1.81484378878349295050043110677506774663925170898e+0000, +/* T0 */ 3.333335997532835641297409611782510896641e-0001, +/* T1 */ 2.999997598248363761541668282006867229939e+00, +}; +/* INDENT ON */ + +#define one q[0] +#define P0 q[1] +#define P1 q[2] +#define P2 q[3] +#define P3 q[4] +#define P4 q[5] +#define P5 q[6] +#define P6 q[7] +#define P7 q[8] +#define T0 q[9] +#define T1 q[10] + +float +__k_tanf(double x, int n) { + float ft = 0.0; + double z, w; + int ix; + + ix = ((int *) &x)[HIWORD] & ~0x80000000; /* ix = leading |x| */ + /* small argument */ + if (ix < 0x3f800000) { /* if |x| < 0.0078125 = 2**-7 */ + if (ix < 0x3f100000) { /* if |x| < 2**-14 */ + if ((int) x == 0) { /* raise inexact if x != 0 */ + ft = n == 0 ? (float) x : (float) (-one / x); + } + return (ft); + } + z = (x * T0) * (T1 + x * x); + ft = n == 0 ? (float) z : (float) (-one / z); + return (ft); + } + z = x * x; + w = ((P0 * x) * (P1 + z * (P2 + z)) * (P3 + z * (P4 + z))) + * (P5 + z * (P6 + z * (P7 + z))); + ft = n == 0 ? (float) w : (float) (-one / w); + return (ft); +} diff --git a/usr/src/lib/libm/common/R/acosf.c b/usr/src/lib/libm/common/R/acosf.c new file mode 100644 index 0000000000..06d4cffd28 --- /dev/null +++ b/usr/src/lib/libm/common/R/acosf.c @@ -0,0 +1,43 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak acosf = __acosf + +#include "libm.h" + +static const float zero = 0.0f; + +float +acosf(float x) { + int ix; + + ix = *(int *)&x & ~0x80000000; + if (ix > 0x3f800000) /* |x| > 1 or x is nan */ + return ((x * zero) / zero); + return ((float)acos((double)x)); +} diff --git a/usr/src/lib/libm/common/R/acoshf.c b/usr/src/lib/libm/common/R/acoshf.c new file mode 100644 index 0000000000..7e0fdac2b1 --- /dev/null +++ b/usr/src/lib/libm/common/R/acoshf.c @@ -0,0 +1,43 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak acoshf = __acoshf + +#include "libm.h" + +static const float zero = 0.0f; + +float +acoshf(float x) { + int hx; + + hx = *(int *)&x; + if (hx < 0x3f800000 || hx > 0x7f800000) /* x < 1 or x is nan */ + return ((x * zero) / zero); + return ((float)acosh((double)x)); +} diff --git a/usr/src/lib/libm/common/R/asinf.c b/usr/src/lib/libm/common/R/asinf.c new file mode 100644 index 0000000000..1588c25f24 --- /dev/null +++ b/usr/src/lib/libm/common/R/asinf.c @@ -0,0 +1,43 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak asinf = __asinf + +#include "libm.h" + +static const float zero = 0.0f; + +float +asinf(float x) { + int ix; + + ix = *(int *)&x & ~0x80000000; + if (ix > 0x3f800000) /* |x| > 1 or x is nan */ + return ((x * zero) / zero); + return ((float)asin((double)x)); +} diff --git a/usr/src/lib/libm/common/R/asinhf.c b/usr/src/lib/libm/common/R/asinhf.c new file mode 100644 index 0000000000..6bc45572fb --- /dev/null +++ b/usr/src/lib/libm/common/R/asinhf.c @@ -0,0 +1,41 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak asinhf = __asinhf + +#include "libm.h" + +float +asinhf(float x) { + if (isnanf(x)) { + return (x * x); /* + -> * for Cheetah */ + } else { + return ((float) asinh((double) x)); + } +} diff --git a/usr/src/lib/libm/common/R/atan2f.c b/usr/src/lib/libm/common/R/atan2f.c new file mode 100644 index 0000000000..2650e5fc0b --- /dev/null +++ b/usr/src/lib/libm/common/R/atan2f.c @@ -0,0 +1,344 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak atan2f = __atan2f + +#include "libm.h" + +#if defined(__i386) && !defined(__amd64) +extern int __swapRP(int); +#endif + +/* + * For i = 0, ..., 192, let x[i] be the double precision number whose + * high order 32 bits are 0x3f900000 + (i << 16) and whose low order + * 32 bits are zero. Then TBL[i] := atan(x[i]) to double precision. + */ + +static const double TBL[] = { + 1.56237286204768313e-02, + 1.66000375562312640e-02, + 1.75763148444955872e-02, + 1.85525586258889763e-02, + 1.95287670414137082e-02, + 2.05049382324763683e-02, + 2.14810703409090559e-02, + 2.24571615089905717e-02, + 2.34332098794675855e-02, + 2.44092135955758099e-02, + 2.53851708010611396e-02, + 2.63610796402007873e-02, + 2.73369382578244127e-02, + 2.83127447993351995e-02, + 2.92884974107309737e-02, + 3.02641942386252458e-02, + 3.12398334302682774e-02, + 3.31909314971115949e-02, + 3.51417768027967800e-02, + 3.70923545503918164e-02, + 3.90426499551669928e-02, + 4.09926482452637811e-02, + 4.29423346623621707e-02, + 4.48916944623464972e-02, + 4.68407129159696539e-02, + 4.87893753095156174e-02, + 5.07376669454602178e-02, + 5.26855731431300420e-02, + 5.46330792393594777e-02, + 5.65801705891457105e-02, + 5.85268325663017702e-02, + 6.04730505641073168e-02, + 6.24188099959573500e-02, + 6.63088949198234884e-02, + 7.01969710718705203e-02, + 7.40829225490337306e-02, + 7.79666338315423008e-02, + 8.18479898030765457e-02, + 8.57268757707448092e-02, + 8.96031774848717461e-02, + 9.34767811585894698e-02, + 9.73475734872236709e-02, + 1.01215441667466668e-01, + 1.05080273416329528e-01, + 1.08941956989865793e-01, + 1.12800381201659389e-01, + 1.16655435441069349e-01, + 1.20507009691224562e-01, + 1.24354994546761438e-01, + 1.32039761614638762e-01, + 1.39708874289163648e-01, + 1.47361481088651630e-01, + 1.54996741923940973e-01, + 1.62613828597948568e-01, + 1.70211925285474408e-01, + 1.77790228992676075e-01, + 1.85347949995694761e-01, + 1.92884312257974672e-01, + 2.00398553825878512e-01, + 2.07889927202262986e-01, + 2.15357699697738048e-01, + 2.22801153759394521e-01, + 2.30219587276843718e-01, + 2.37612313865471242e-01, + 2.44978663126864143e-01, + 2.59629629408257512e-01, + 2.74167451119658789e-01, + 2.88587361894077410e-01, + 3.02884868374971417e-01, + 3.17055753209147029e-01, + 3.31096076704132103e-01, + 3.45002177207105132e-01, + 3.58770670270572245e-01, + 3.72398446676754202e-01, + 3.85882669398073752e-01, + 3.99220769575252543e-01, + 4.12410441597387323e-01, + 4.25449637370042266e-01, + 4.38336559857957830e-01, + 4.51069655988523499e-01, + 4.63647609000806094e-01, + 4.88333951056405535e-01, + 5.12389460310737732e-01, + 5.35811237960463704e-01, + 5.58599315343562441e-01, + 5.80756353567670414e-01, + 6.02287346134964152e-01, + 6.23199329934065904e-01, + 6.43501108793284371e-01, + 6.63202992706093286e-01, + 6.82316554874748071e-01, + 7.00854407884450192e-01, + 7.18829999621624527e-01, + 7.36257428981428097e-01, + 7.53151280962194414e-01, + 7.69526480405658297e-01, + 7.85398163397448279e-01, + 8.15691923316223422e-01, + 8.44153986113171051e-01, + 8.70903457075652976e-01, + 8.96055384571343927e-01, + 9.19719605350416858e-01, + 9.42000040379463610e-01, + 9.62994330680936206e-01, + 9.82793723247329054e-01, + 1.00148313569423464e+00, + 1.01914134426634972e+00, + 1.03584125300880014e+00, + 1.05165021254837376e+00, + 1.06663036531574362e+00, + 1.08083900054116833e+00, + 1.09432890732118993e+00, + 1.10714871779409041e+00, + 1.13095374397916038e+00, + 1.15257199721566761e+00, + 1.17227388112847630e+00, + 1.19028994968253166e+00, + 1.20681737028525249e+00, + 1.22202532321098967e+00, + 1.23605948947808186e+00, + 1.24904577239825443e+00, + 1.26109338225244039e+00, + 1.27229739520871732e+00, + 1.28274087974427076e+00, + 1.29249666778978534e+00, + 1.30162883400919616e+00, + 1.31019393504755555e+00, + 1.31824205101683711e+00, + 1.32581766366803255e+00, + 1.33970565959899957e+00, + 1.35212738092095464e+00, + 1.36330010035969384e+00, + 1.37340076694501589e+00, + 1.38257482149012589e+00, + 1.39094282700241845e+00, + 1.39860551227195762e+00, + 1.40564764938026987e+00, + 1.41214106460849531e+00, + 1.41814699839963154e+00, + 1.42371797140649403e+00, + 1.42889927219073276e+00, + 1.43373015248470903e+00, + 1.43824479449822262e+00, + 1.44247309910910193e+00, + 1.44644133224813509e+00, + 1.45368758222803240e+00, + 1.46013910562100091e+00, + 1.46591938806466282e+00, + 1.47112767430373470e+00, + 1.47584462045214027e+00, + 1.48013643959415142e+00, + 1.48405798811891154e+00, + 1.48765509490645531e+00, + 1.49096634108265924e+00, + 1.49402443552511865e+00, + 1.49685728913695626e+00, + 1.49948886200960629e+00, + 1.50193983749385196e+00, + 1.50422816301907281e+00, + 1.50636948736934317e+00, + 1.50837751679893928e+00, + 1.51204050407917401e+00, + 1.51529782154917969e+00, + 1.51821326518395483e+00, + 1.52083793107295384e+00, + 1.52321322351791322e+00, + 1.52537304737331958e+00, + 1.52734543140336587e+00, + 1.52915374769630819e+00, + 1.53081763967160667e+00, + 1.53235373677370856e+00, + 1.53377621092096650e+00, + 1.53509721411557254e+00, + 1.53632722579538861e+00, + 1.53747533091664934e+00, + 1.53854944435964280e+00, + 1.53955649336462841e+00, + 1.54139303859089161e+00, + 1.54302569020147562e+00, + 1.54448660954197448e+00, + 1.54580153317597646e+00, + 1.54699130060982659e+00, + 1.54807296595325550e+00, + 1.54906061995310385e+00, + 1.54996600675867957e+00, + 1.55079899282174605e+00, + 1.55156792769518947e+00, + 1.55227992472688747e+00, + 1.55294108165534417e+00, + 1.55355665560036682e+00, + 1.55413120308095598e+00, + 1.55466869295126031e+00, + 1.55517259817441977e+00, +}; + +static const double + pio4 = 7.8539816339744827900e-01, + pio2 = 1.5707963267948965580e+00, + negpi = -3.1415926535897931160e+00, + q1 = -3.3333333333296428046e-01, + q2 = 1.9999999186853752618e-01, + zero = 0.0; + +static const float two24 = 16777216.0; + +float +atan2f(float fy, float fx) +{ + double a, t, s, dbase; + float x, y, base; + int i, k, hx, hy, ix, iy, sign; +#if defined(__i386) && !defined(__amd64) + int rp; +#endif + + iy = *(int *)&fy; + ix = *(int *)&fx; + hy = iy & ~0x80000000; + hx = ix & ~0x80000000; + + sign = 0; + if (hy > hx) { + x = fy; + y = fx; + i = hx; + hx = hy; + hy = i; + if (iy < 0) { + x = -x; + sign = 1; + } + if (ix < 0) { + y = -y; + a = pio2; + } else { + a = -pio2; + sign = 1 - sign; + } + } else { + y = fy; + x = fx; + if (iy < 0) { + y = -y; + sign = 1; + } + if (ix < 0) { + x = -x; + a = negpi; + sign = 1 - sign; + } else { + a = zero; + } + } + + if (hx >= 0x7f800000 || hx - hy >= 0x0c800000) { + if (hx >= 0x7f800000) { + if (hx > 0x7f800000) /* nan */ + return (x * y); + else if (hy >= 0x7f800000) + a += pio4; + } else if ((int)a == 0) { + a = (double)y / x; + } + return ((float)((sign)? -a : a)); + } + + if (hy < 0x00800000) { + if (hy == 0) + return ((float)((sign)? -a : a)); + /* scale subnormal y */ + y *= two24; + x *= two24; + hy = *(int *)&y; + hx = *(int *)&x; + } + +#if defined(__i386) && !defined(__amd64) + rp = __swapRP(fp_extended); +#endif + k = (hy - hx + 0x3f800000) & 0xfff80000; + if (k >= 0x3c800000) { /* |y/x| >= 1/64 */ + *(int *)&base = k; + k = (k - 0x3c800000) >> 19; + a += TBL[k]; + } else { + /* + * For some reason this is faster on USIII than just + * doing t = y/x in this case. + */ + *(int *)&base = 0; + } + dbase = (double)base; + t = (y - x * dbase) / (x + y * dbase); + s = t * t; + a = (a + t) + t * s * (q1 + s * q2); +#if defined(__i386) && !defined(__amd64) + if (rp != fp_extended) + (void) __swapRP(rp); +#endif + return ((float)((sign)? -a : a)); +} diff --git a/usr/src/lib/libm/common/R/atan2pif.c b/usr/src/lib/libm/common/R/atan2pif.c new file mode 100644 index 0000000000..76f104db17 --- /dev/null +++ b/usr/src/lib/libm/common/R/atan2pif.c @@ -0,0 +1,52 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak atan2pif = __atan2pif + +#include "libm.h" + +static const double invpi = 0.3183098861837906715377675; + +float +atan2pif(float y, float x) { + int ix, iy, hx, hy; + + ix = *(int *)&x; + iy = *(int *)&y; + hx = ix & ~0x80000000; + hy = iy & ~0x80000000; + if (hx > 0x7f800000 || hy > 0x7f800000) /* x or y is nan */ + return (x * y); + if ((hx | hy) == 0) { + /* x and y are both zero */ + if (ix == 0) + return (y); + return ((iy == 0)? 1.0f : -1.0f); + } + return ((float)(invpi * atan2((double)y, (double)x))); +} diff --git a/usr/src/lib/libm/common/R/atanf.c b/usr/src/lib/libm/common/R/atanf.c new file mode 100644 index 0000000000..b68c48cca8 --- /dev/null +++ b/usr/src/lib/libm/common/R/atanf.c @@ -0,0 +1,196 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak atanf = __atanf + +/* INDENT OFF */ +/* + * float atanf(float x); + * Table look-up algorithm + * By K.C. Ng, March 9, 1989 + * + * Algorithm. + * + * The algorithm is based on atan(x)=atan(y)+atan((x-y)/(1+x*y)). + * We use poly1(x) to approximate atan(x) for x in [0,1/8] with + * error (relative) + * |(atan(x)-poly1(x))/x|<= 2^-115.94 long double + * |(atan(x)-poly1(x))/x|<= 2^-58.85 double + * |(atan(x)-poly1(x))/x|<= 2^-25.53 float + * and use poly2(x) to approximate atan(x) for x in [0,1/65] with + * error (absolute) + * |atan(x)-poly2(x)|<= 2^-122.15 long double + * |atan(x)-poly2(x)|<= 2^-64.79 double + * |atan(x)-poly2(x)|<= 2^-35.36 float + * and use poly3(x) to approximate atan(x) for x in [1/8,7/16] with + * error (relative, on for single precision) + * |(atan(x)-poly1(x))/x|<= 2^-25.53 float + * + * Here poly1-3 are odd polynomial with the following form: + * x + x^3*(a1+x^2*(a2+...)) + * + * (0). Purge off Inf and NaN and 0 + * (1). Reduce x to positive by atan(x) = -atan(-x). + * (2). For x <= 1/8, use + * (2.1) if x < 2^(-prec/2-2), atan(x) = x with inexact + * (2.2) Otherwise + * atan(x) = poly1(x) + * (3). For x >= 8 then + * (3.1) if x >= 2^(prec+2), atan(x) = atan(inf) - pio2lo + * (3.2) if x >= 2^(prec/3+2), atan(x) = atan(inf) - 1/x + * (3.3) if x > 65, atan(x) = atan(inf) - poly2(1/x) + * (3.4) Otherwise, atan(x) = atan(inf) - poly1(1/x) + * + * (4). Now x is in (0.125, 8) + * Find y that match x to 4.5 bit after binary (easy). + * If iy is the high word of y, then + * single : j = (iy - 0x3e000000) >> 19 + * (single is modified to (iy-0x3f000000)>>19) + * double : j = (iy - 0x3fc00000) >> 16 + * quad : j = (iy - 0x3ffc0000) >> 12 + * + * Let s = (x-y)/(1+x*y). Then + * atan(x) = atan(y) + poly1(s) + * = _TBL_r_atan_hi[j] + (_TBL_r_atan_lo[j] + poly2(s) ) + * + * Note. |s| <= 1.5384615385e-02 = 1/65. Maxium occurs at x = 1.03125 + * + */ + +#include "libm.h" + +extern const float _TBL_r_atan_hi[], _TBL_r_atan_lo[]; +static const float + big = 1.0e37F, + one = 1.0F, + p1 = -3.333185951111688247225368498733544672172e-0001F, + p2 = 1.969352894213455405211341983203180636021e-0001F, + q1 = -3.332921964095646819563419704110132937456e-0001F, + a1 = -3.333323465223893614063523351509338934592e-0001F, + a2 = 1.999425625935277805494082274808174062403e-0001F, + a3 = -1.417547090509737780085769846290301788559e-0001F, + a4 = 1.016250813871991983097273733227432685084e-0001F, + a5 = -5.137023693688358515753093811791755221805e-0002F, + pio2hi = 1.570796371e+0000F, + pio2lo = -4.371139000e-0008F; +/* INDENT ON */ + +float +atanf(float xx) { + float x, y, z, r, p, s; + volatile double dummy; + int ix, iy, sign, j; + + x = xx; + ix = *(int *) &x; + sign = ix & 0x80000000; + ix ^= sign; + + /* for |x| < 1/8 */ + if (ix < 0x3e000000) { + if (ix < 0x38800000) { /* if |x| < 2**(-prec/2-2) */ + dummy = big + x; /* get inexact flag if x != 0 */ +#ifdef lint + dummy = dummy; +#endif + return (x); + } + z = x * x; + if (ix < 0x3c000000) { /* if |x| < 2**(-prec/4-1) */ + x = x + (x * z) * p1; + return (x); + } else { + x = x + (x * z) * (p1 + z * p2); + return (x); + } + } + + /* for |x| >= 8.0 */ + if (ix >= 0x41000000) { + *(int *) &x = ix; + if (ix < 0x42820000) { /* x < 65 */ + r = one / x; + z = r * r; + y = r * (one + z * (p1 + z * p2)); /* poly1 */ + y -= pio2lo; + } else if (ix < 0x44800000) { /* x < 2**(prec/3+2) */ + r = one / x; + z = r * r; + y = r * (one + z * q1); /* poly2 */ + y -= pio2lo; + } else if (ix < 0x4c800000) { /* x < 2**(prec+2) */ + y = one / x - pio2lo; + } else if (ix < 0x7f800000) { /* x < inf */ + y = -pio2lo; + } else { /* x is inf or NaN */ + if (ix > 0x7f800000) { + return (x * x); /* - -> * for Cheetah */ + } + y = -pio2lo; + } + + if (sign == 0) + x = pio2hi - y; + else + x = y - pio2hi; + return (x); + } + + + /* now x is between 1/8 and 8 */ + if (ix < 0x3f000000) { /* between 1/8 and 1/2 */ + z = x * x; + x = x + (x * z) * (a1 + z * (a2 + z * (a3 + z * (a4 + + z * a5)))); + return (x); + } + *(int *) &x = ix; + iy = (ix + 0x00040000) & 0x7ff80000; + *(int *) &y = iy; + j = (iy - 0x3f000000) >> 19; + + if (ix == iy) + p = x - y; /* p=0.0 */ + else { + if (sign == 0) + s = (x - y) / (one + x * y); + else + s = (y - x) / (one + x * y); + z = s * s; + p = s * (one + z * q1); + } + if (sign == 0) { + r = p + _TBL_r_atan_lo[j]; + x = r + _TBL_r_atan_hi[j]; + } else { + r = p - _TBL_r_atan_lo[j]; + x = r - _TBL_r_atan_hi[j]; + } + return (x); +} diff --git a/usr/src/lib/libm/common/R/atanhf.c b/usr/src/lib/libm/common/R/atanhf.c new file mode 100644 index 0000000000..2d150aa9b2 --- /dev/null +++ b/usr/src/lib/libm/common/R/atanhf.c @@ -0,0 +1,45 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak atanhf = __atanhf + +#include "libm.h" + +static const float zero = 0.0f; + +float +atanhf(float x) { + int ix; + + ix = *((int *)&x) & ~0x80000000; + if (ix > 0x3f800000) /* |x| > 1 or x is nan */ + return ((x * zero) / zero); + if (ix == 0x3f800000) /* |x| == 1 */ + return (x / zero); + return ((float)atanh((double)x)); +} diff --git a/usr/src/lib/libm/common/R/besself.c b/usr/src/lib/libm/common/R/besself.c new file mode 100644 index 0000000000..720e4eb47f --- /dev/null +++ b/usr/src/lib/libm/common/R/besself.c @@ -0,0 +1,807 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak j0f = __j0f +#pragma weak j1f = __j1f +#pragma weak jnf = __jnf +#pragma weak y0f = __y0f +#pragma weak y1f = __y1f +#pragma weak ynf = __ynf + +#include "libm.h" +#include <float.h> + +#if defined(__i386) && !defined(__amd64) +extern int __swapRP(int); +#endif + +static const float + zerof = 0.0f, + onef = 1.0f; + +static const double C[] = { + 0.0, + -0.125, + 0.25, + 0.375, + 0.5, + 1.0, + 2.0, + 8.0, + 0.5641895835477562869480794515607725858441, /* 1/sqrt(pi) */ + 0.636619772367581343075535053490057448, /* 2/pi */ + 1.0e9, +}; + +#define zero C[0] +#define neighth C[1] +#define quarter C[2] +#define three8 C[3] +#define half C[4] +#define one C[5] +#define two C[6] +#define eight C[7] +#define isqrtpi C[8] +#define tpi C[9] +#define big C[10] + +static const double Cj0y0[] = { + 0.4861344183386052721391238447e5, /* pr */ + 0.1377662549407112278133438945e6, + 0.1222466364088289731869114004e6, + 0.4107070084315176135583353374e5, + 0.5026073801860637125889039915e4, + 0.1783193659125479654541542419e3, + 0.88010344055383421691677564e0, + 0.4861344183386052721414037058e5, /* ps */ + 0.1378196632630384670477582699e6, + 0.1223967185341006542748936787e6, + 0.4120150243795353639995862617e5, + 0.5068271181053546392490184353e4, + 0.1829817905472769960535671664e3, + 1.0, + -0.1731210995701068539185611951e3, /* qr */ + -0.5522559165936166961235240613e3, + -0.5604935606637346590614529613e3, + -0.2200430300226009379477365011e3, + -0.323869355375648849771296746e2, + -0.14294979207907956223499258e1, + -0.834690374102384988158918e-2, + 0.1107975037248683865326709645e5, /* qs */ + 0.3544581680627082674651471873e5, + 0.3619118937918394132179019059e5, + 0.1439895563565398007471485822e5, + 0.2190277023344363955930226234e4, + 0.106695157020407986137501682e3, + 1.0, +}; + +#define pr Cj0y0 +#define ps (Cj0y0+7) +#define qr (Cj0y0+14) +#define qs (Cj0y0+21) + +static const double Cj0[] = { + -2.500000000000003622131880894830476755537e-0001, /* r0 */ + 1.095597547334830263234433855932375353303e-0002, + -1.819734750463320921799187258987098087697e-0004, + 9.977001946806131657544212501069893930846e-0007, + 1.0, /* s0 */ + 1.867609810662950169966782360588199673741e-0002, + 1.590389206181565490878430827706972074208e-0004, + 6.520867386742583632375520147714499522721e-0007, + 9.999999999999999942156495584397047660949e-0001, /* r1 */ + -2.389887722731319130476839836908143731281e-0001, + 1.293359476138939027791270393439493640570e-0002, + -2.770985642343140122168852400228563364082e-0004, + 2.905241575772067678086738389169625218912e-0006, + -1.636846356264052597969042009265043251279e-0008, + 5.072306160724884775085431059052611737827e-0011, + -8.187060730684066824228914775146536139112e-0014, + 5.422219326959949863954297860723723423842e-0017, + 1.0, /* s1 */ + 1.101122772686807702762104741932076228349e-0002, + 6.140169310641649223411427764669143978228e-0005, + 2.292035877515152097976946119293215705250e-0007, + 6.356910426504644334558832036362219583789e-0010, + 1.366626326900219555045096999553948891401e-0012, + 2.280399586866739522891837985560481180088e-0015, + 2.801559820648939665270492520004836611187e-0018, + 2.073101088320349159764410261466350732968e-0021, +}; + +#define r0 Cj0 +#define s0 (Cj0+4) +#define r1 (Cj0+8) +#define s1 (Cj0+17) + +static const double Cy0[] = { + -7.380429510868722526754723020704317641941e-0002, /* u0 */ + 1.772607102684869924301459663049874294814e-0001, + -1.524370666542713828604078090970799356306e-0002, + 4.650819100693891757143771557629924591915e-0004, + -7.125768872339528975036316108718239946022e-0006, + 6.411017001656104598327565004771515257146e-0008, + -3.694275157433032553021246812379258781665e-0010, + 1.434364544206266624252820889648445263842e-0012, + -3.852064731859936455895036286874139896861e-0015, + 7.182052899726138381739945881914874579696e-0018, + -9.060556574619677567323741194079797987200e-0021, + 7.124435467408860515265552217131230511455e-0024, + -2.709726774636397615328813121715432044771e-0027, + 1.0, /* v0 */ + 4.678678931512549002587702477349214886475e-0003, + 9.486828955529948534822800829497565178985e-0006, + 1.001495929158861646659010844136682454906e-0008, + 4.725338116256021660204443235685358593611e-0012, +}; + +#define u0 Cy0 +#define v0 (Cy0+13) + +static const double Cj1y1[] = { + -0.4435757816794127857114720794e7, /* pr0 */ + -0.9942246505077641195658377899e7, + -0.6603373248364939109255245434e7, + -0.1523529351181137383255105722e7, + -0.1098240554345934672737413139e6, + -0.1611616644324610116477412898e4, + -0.4435757816794127856828016962e7, /* ps0 */ + -0.9934124389934585658967556309e7, + -0.6585339479723087072826915069e7, + -0.1511809506634160881644546358e7, + -0.1072638599110382011903063867e6, + -0.1455009440190496182453565068e4, + 0.3322091340985722351859704442e5, /* qr0 */ + 0.8514516067533570196555001171e5, + 0.6617883658127083517939992166e5, + 0.1849426287322386679652009819e5, + 0.1706375429020768002061283546e4, + 0.3526513384663603218592175580e2, + 0.7087128194102874357377502472e6, /* qs0 */ + 0.1819458042243997298924553839e7, + 0.1419460669603720892855755253e7, + 0.4002944358226697511708610813e6, + 0.3789022974577220264142952256e5, + 0.8638367769604990967475517183e3, +}; + +#define pr0 Cj1y1 +#define ps0 (Cj1y1+6) +#define qr0 (Cj1y1+12) +#define qs0 (Cj1y1+18) + +static const double Cj1[] = { + -6.250000000000002203053200981413218949548e-0002, /* a0 */ + 1.600998455640072901321605101981501263762e-0003, + -1.963888815948313758552511884390162864930e-0005, + 8.263917341093549759781339713418201620998e-0008, + 1.0e0, /* b0 */ + 1.605069137643004242395356851797873766927e-0002, + 1.149454623251299996428500249509098499383e-0004, + 3.849701673735260970379681807910852327825e-0007, + 4.999999999999999995517408894340485471724e-0001, + -6.003825028120475684835384519945468075423e-0002, + 2.301719899263321828388344461995355419832e-0003, + -4.208494869238892934859525221654040304068e-0005, + 4.377745135188837783031540029700282443388e-0007, + -2.854106755678624335145364226735677754179e-0009, + 1.234002865443952024332943901323798413689e-0011, + -3.645498437039791058951273508838177134310e-0014, + 7.404320596071797459925377103787837414422e-0017, + -1.009457448277522275262808398517024439084e-0019, + 8.520158355824819796968771418801019930585e-0023, + -3.458159926081163274483854614601091361424e-0026, + 1.0e0, /* b1 */ + 4.923499437590484879081138588998986303306e-0003, + 1.054389489212184156499666953501976688452e-0005, + 1.180768373106166527048240364872043816050e-0008, + 5.942665743476099355323245707680648588540e-0012, +}; + +#define a0 Cj1 +#define b0 (Cj1+4) +#define a1 (Cj1+8) +#define b1 (Cj1+20) + +static const double Cy1[] = { + -1.960570906462389461018983259589655961560e-0001, /* c0 */ + 4.931824118350661953459180060007970291139e-0002, + -1.626975871565393656845930125424683008677e-0003, + 1.359657517926394132692884168082224258360e-0005, + 1.0e0, /* d0 */ + 2.565807214838390835108224713630901653793e-0002, + 3.374175208978404268650522752520906231508e-0004, + 2.840368571306070719539936935220728843177e-0006, + 1.396387402048998277638900944415752207592e-0008, + -1.960570906462389473336339614647555351626e-0001, /* c1 */ + 5.336268030335074494231369159933012844735e-0002, + -2.684137504382748094149184541866332033280e-0003, + 5.737671618979185736981543498580051903060e-0005, + -6.642696350686335339171171785557663224892e-0007, + 4.692417922568160354012347591960362101664e-0009, + -2.161728635907789319335231338621412258355e-0011, + 6.727353419738316107197644431844194668702e-0014, + -1.427502986803861372125234355906790573422e-0016, + 2.020392498726806769468143219616642940371e-0019, + -1.761371948595104156753045457888272716340e-0022, + 7.352828391941157905175042420249225115816e-0026, + 1.0e0, /* d1 */ + 5.029187436727947764916247076102283399442e-0003, + 1.102693095808242775074856548927801750627e-0005, + 1.268035774543174837829534603830227216291e-0008, + 6.579416271766610825192542295821308730206e-0012, +}; + +#define c0 Cy1 +#define d0 (Cy1+4) +#define c1 (Cy1+9) +#define d1 (Cy1+21) + + +/* core of j0f computation; assumes fx is finite */ +static double +__k_j0f(float fx) +{ + double x, z, s, c, ss, cc, r, t, p0, q0; + int ix, i; + + ix = *(int *)&fx & ~0x80000000; + x = fabs((double)fx); + if (ix > 0x41000000) { + /* x > 8; see comments in j0.c */ + s = sin(x); + c = cos(x); + if (signbit(s) != signbit(c)) { + ss = s - c; + cc = -cos(x + x) / ss; + } else { + cc = s + c; + ss = -cos(x + x) / cc; + } + if (ix > 0x501502f9) { + /* x > 1.0e10 */ + p0 = one; + q0 = neighth / x; + } else { + t = eight / x; + z = t * t; + p0 = (pr[0] + z * (pr[1] + z * (pr[2] + z * (pr[3] + + z * (pr[4] + z * (pr[5] + z * pr[6])))))) / + (ps[0] + z * (ps[1] + z * (ps[2] + z * (ps[3] + + z * (ps[4] + z * (ps[5] + z)))))); + q0 = ((qr[0] + z * (qr[1] + z * (qr[2] + z * (qr[3] + + z * (qr[4] + z * (qr[5] + z * qr[6])))))) / + (qs[0] + z * (qs[1] + z * (qs[2] + z * (qs[3] + + z * (qs[4] + z * (qs[5] + z))))))) * t; + } + return (isqrtpi * (p0 * cc - q0 * ss) / sqrt(x)); + } + if (ix <= 0x3727c5ac) { + /* x <= 1.0e-5 */ + if (ix <= 0x219392ef) /* x <= 1.0e-18 */ + return (one - x); + return (one - x * x * quarter); + } + z = x * x; + if (ix <= 0x3fa3d70a) { + /* x <= 1.28 */ + r = r0[0] + z * (r0[1] + z * (r0[2] + z * r0[3])); + s = s0[0] + z * (s0[1] + z * (s0[2] + z * s0[3])); + return (one + z * (r / s)); + } + r = r1[8]; + s = s1[8]; + for (i = 7; i >= 0; i--) { + r = r * z + r1[i]; + s = s * z + s1[i]; + } + return (r / s); +} + +float +j0f(float fx) +{ + float f; + int ix; +#if defined(__i386) && !defined(__amd64) + int rp; +#endif + + ix = *(int *)&fx & ~0x80000000; + if (ix >= 0x7f800000) { /* nan or inf */ + if (ix > 0x7f800000) + return (fx * fx); + return (zerof); + } + +#if defined(__i386) && !defined(__amd64) + rp = __swapRP(fp_extended); +#endif + f = (float)__k_j0f(fx); +#if defined(__i386) && !defined(__amd64) + if (rp != fp_extended) + (void) __swapRP(rp); +#endif + return (f); +} + +/* core of y0f computation; assumes fx is finite and positive */ +static double +__k_y0f(float fx) +{ + double x, z, s, c, ss, cc, t, p0, q0, u, v; + int ix, i; + + ix = *(int *)&fx; + x = (double)fx; + if (ix > 0x41000000) { + /* x > 8; see comments in j0.c */ + s = sin(x); + c = cos(x); + if (signbit(s) != signbit(c)) { + ss = s - c; + cc = -cos(x + x) / ss; + } else { + cc = s + c; + ss = -cos(x + x) / cc; + } + if (ix > 0x501502f9) { + /* x > 1.0e10 */ + p0 = one; + q0 = neighth / x; + } else { + t = eight / x; + z = t * t; + p0 = (pr[0] + z * (pr[1] + z * (pr[2] + z * (pr[3] + + z * (pr[4] + z * (pr[5] + z * pr[6])))))) / + (ps[0] + z * (ps[1] + z * (ps[2] + z * (ps[3] + + z * (ps[4] + z * (ps[5] + z)))))); + q0 = ((qr[0] + z * (qr[1] + z * (qr[2] + z * (qr[3] + + z * (qr[4] + z * (qr[5] + z * qr[6])))))) / + (qs[0] + z * (qs[1] + z * (qs[2] + z * (qs[3] + + z * (qs[4] + z * (qs[5] + z))))))) * t; + } + return (isqrtpi * (p0 * ss + q0 * cc) / sqrt(x)); + } + if (ix <= 0x219392ef) /* x <= 1.0e-18 */ + return (u0[0] + tpi * log(x)); + z = x * x; + u = u0[12]; + for (i = 11; i >= 0; i--) + u = u * z + u0[i]; + v = v0[0] + z * (v0[1] + z * (v0[2] + z * (v0[3] + z * v0[4]))); + return (u / v + tpi * (__k_j0f(fx) * log(x))); +} + +float +y0f(float fx) +{ + float f; + int ix; +#if defined(__i386) && !defined(__amd64) + int rp; +#endif + + ix = *(int *)&fx; + if ((ix & ~0x80000000) > 0x7f800000) /* nan */ + return (fx * fx); + if (ix <= 0) { /* zero or negative */ + if ((ix << 1) == 0) + return (-onef / zerof); + return (zerof / zerof); + } + if (ix == 0x7f800000) /* +inf */ + return (zerof); + +#if defined(__i386) && !defined(__amd64) + rp = __swapRP(fp_extended); +#endif + f = (float)__k_y0f(fx); +#if defined(__i386) && !defined(__amd64) + if (rp != fp_extended) + (void) __swapRP(rp); +#endif + return (f); +} + +/* core of j1f computation; assumes fx is finite */ +static double +__k_j1f(float fx) +{ + double x, z, s, c, ss, cc, r, t, p1, q1; + int i, ix, sgn; + + ix = *(int *)&fx; + sgn = (unsigned)ix >> 31; + ix &= ~0x80000000; + x = fabs((double)fx); + if (ix > 0x41000000) { + /* x > 8; see comments in j1.c */ + s = sin(x); + c = cos(x); + if (signbit(s) != signbit(c)) { + cc = s - c; + ss = cos(x + x) / cc; + } else { + ss = -s - c; + cc = cos(x + x) / ss; + } + if (ix > 0x501502f9) { + /* x > 1.0e10 */ + p1 = one; + q1 = three8 / x; + } else { + t = eight / x; + z = t * t; + p1 = (pr0[0] + z * (pr0[1] + z * (pr0[2] + z * + (pr0[3] + z * (pr0[4] + z * pr0[5]))))) / + (ps0[0] + z * (ps0[1] + z * (ps0[2] + z * + (ps0[3] + z * (ps0[4] + z * (ps0[5] + z)))))); + q1 = ((qr0[0] + z * (qr0[1] + z * (qr0[2] + z * + (qr0[3] + z * (qr0[4] + z * qr0[5]))))) / + (qs0[0] + z * (qs0[1] + z * (qs0[2] + z * + (qs0[3] + z * (qs0[4] + z * (qs0[5] + z))))))) * t; + } + t = isqrtpi * (p1 * cc - q1 * ss) / sqrt(x); + return ((sgn)? -t : t); + } + if (ix <= 0x3727c5ac) { + /* x <= 1.0e-5 */ + if (ix <= 0x219392ef) /* x <= 1.0e-18 */ + t = half * x; + else + t = x * (half + neighth * x * x); + return ((sgn)? -t : t); + } + z = x * x; + if (ix < 0x3fa3d70a) { + /* x < 1.28 */ + r = a0[0] + z * (a0[1] + z * (a0[2] + z * a0[3])); + s = b0[0] + z * (b0[1] + z * (b0[2] + z * b0[3])); + t = x * half + x * (z * (r / s)); + } else { + r = a1[11]; + for (i = 10; i >= 0; i--) + r = r * z + a1[i]; + s = b1[0] + z * (b1[1] + z * (b1[2] + z * (b1[3] + z * b1[4]))); + t = x * (r / s); + } + return ((sgn)? -t : t); +} + +float +j1f(float fx) +{ + float f; + int ix; +#if defined(__i386) && !defined(__amd64) + int rp; +#endif + + ix = *(int *)&fx & ~0x80000000; + if (ix >= 0x7f800000) /* nan or inf */ + return (onef / fx); + +#if defined(__i386) && !defined(__amd64) + rp = __swapRP(fp_extended); +#endif + f = (float)__k_j1f(fx); +#if defined(__i386) && !defined(__amd64) + if (rp != fp_extended) + (void) __swapRP(rp); +#endif + return (f); +} + +/* core of y1f computation; assumes fx is finite and positive */ +static double +__k_y1f(float fx) +{ + double x, z, s, c, ss, cc, u, v, p1, q1, t; + int i, ix; + + ix = *(int *)&fx; + x = (double)fx; + if (ix > 0x41000000) { + /* x > 8; see comments in j1.c */ + s = sin(x); + c = cos(x); + if (signbit(s) != signbit(c)) { + cc = s - c; + ss = cos(x + x) / cc; + } else { + ss = -s - c; + cc = cos(x + x) / ss; + } + if (ix > 0x501502f9) { + /* x > 1.0e10 */ + p1 = one; + q1 = three8 / x; + } else { + t = eight / x; + z = t * t; + p1 = (pr0[0] + z * (pr0[1] + z * (pr0[2] + z * + (pr0[3] + z * (pr0[4] + z * pr0[5]))))) / + (ps0[0] + z * (ps0[1] + z * (ps0[2] + z * + (ps0[3] + z * (ps0[4] + z * (ps0[5] + z)))))); + q1 = ((qr0[0] + z * (qr0[1] + z * (qr0[2] + z * + (qr0[3] + z * (qr0[4] + z * qr0[5]))))) / + (qs0[0] + z * (qs0[1] + z * (qs0[2] + z * + (qs0[3] + z * (qs0[4] + z * (qs0[5] + z))))))) * t; + } + return (isqrtpi * (p1 * ss + q1 * cc) / sqrt(x)); + } + if (ix <= 0x219392ef) /* x <= 1.0e-18 */ + return (-tpi / x); + z = x * x; + if (ix < 0x3fa3d70a) { + /* x < 1.28 */ + u = c0[0] + z * (c0[1] + z * (c0[2] + z * c0[3])); + v = d0[0] + z * (d0[1] + z * (d0[2] + z * (d0[3] + z * d0[4]))); + } else { + u = c1[11]; + for (i = 10; i >= 0; i--) + u = u * z + c1[i]; + v = d1[0] + z * (d1[1] + z * (d1[2] + z * (d1[3] + z * d1[4]))); + } + return (x * (u / v) + tpi * (__k_j1f(fx) * log(x) - one / x)); +} + +float +y1f(float fx) +{ + float f; + int ix; +#if defined(__i386) && !defined(__amd64) + int rp; +#endif + + ix = *(int *)&fx; + if ((ix & ~0x80000000) > 0x7f800000) /* nan */ + return (fx * fx); + if (ix <= 0) { /* zero or negative */ + if ((ix << 1) == 0) + return (-onef / zerof); + return (zerof / zerof); + } + if (ix == 0x7f800000) /* +inf */ + return (zerof); + +#if defined(__i386) && !defined(__amd64) + rp = __swapRP(fp_extended); +#endif + f = (float)__k_y1f(fx); +#if defined(__i386) && !defined(__amd64) + if (rp != fp_extended) + (void) __swapRP(rp); +#endif + return (f); +} + +float +jnf(int n, float fx) +{ + double a, b, temp, x, z, w, t, q0, q1, h; + float f; + int i, ix, sgn, m, k; +#if defined(__i386) && !defined(__amd64) + int rp; +#endif + + if (n < 0) { + n = -n; + fx = -fx; + } + if (n == 0) + return (j0f(fx)); + if (n == 1) + return (j1f(fx)); + + ix = *(int *)&fx; + sgn = (n & 1)? ((unsigned)ix >> 31) : 0; + ix &= ~0x80000000; + if (ix >= 0x7f800000) { /* nan or inf */ + if (ix > 0x7f800000) + return (fx * fx); + return ((sgn)? -zerof : zerof); + } + if ((ix << 1) == 0) + return ((sgn)? -zerof : zerof); + +#if defined(__i386) && !defined(__amd64) + rp = __swapRP(fp_extended); +#endif + fx = fabsf(fx); + x = (double)fx; + if ((double)n <= x) { + /* safe to use J(n+1,x) = 2n/x * J(n,x) - J(n-1,x) */ + a = __k_j0f(fx); + b = __k_j1f(fx); + for (i = 1; i < n; i++) { + temp = b; + b = b * ((double)(i + i) / x) - a; + a = temp; + } + f = (float)b; +#if defined(__i386) && !defined(__amd64) + if (rp != fp_extended) + (void) __swapRP(rp); +#endif + return ((sgn)? -f : f); + } + if (ix < 0x3089705f) { + /* x < 1.0e-9; use J(n,x) = 1/n! * (x / 2)^n */ + if (n > 6) + n = 6; /* result underflows to zero for n >= 6 */ + b = t = half * x; + a = one; + for (i = 2; i <= n; i++) { + b *= t; + a *= (double)i; + } + b /= a; + } else { + /* + * Use the backward recurrence: + * + * x x^2 x^2 + * J(n,x)/J(n-1,x) = ---- - ------ - ------ ..... + * 2n 2(n+1) 2(n+2) + * + * Let w = 2n/x and h = 2/x. Then the above quotient + * is equal to the continued fraction: + * 1 + * = ----------------------- + * 1 + * w - ----------------- + * 1 + * w+h - --------- + * w+2h - ... + * + * To determine how many terms are needed, run the + * recurrence + * + * Q(0) = w, + * Q(1) = w(w+h) - 1, + * Q(k) = (w+k*h)*Q(k-1) - Q(k-2). + * + * Then when Q(k) > 1e4, k is large enough for single + * precision. + */ +/* XXX NOT DONE - rework this */ + w = (n + n) / x; + h = two / x; + q0 = w; + z = w + h; + q1 = w * z - one; + k = 1; + while (q1 < big) { + k++; + z += h; + temp = z * q1 - q0; + q0 = q1; + q1 = temp; + } + m = n + n; + t = zero; + for (i = (n + k) << 1; i >= m; i -= 2) + t = one / ((double)i / x - t); + a = t; + b = one; + /* + * estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n) + * hence, if n*(log(2n/x)) > ... + * single 8.8722839355e+01 + * double 7.09782712893383973096e+02 + * then recurrent value may overflow and the result is + * likely underflow to zero + */ + temp = (double)n; + temp *= log((two / x) * temp); + if (temp < 7.09782712893383973096e+02) { + for (i = n - 1; i > 0; i--) { + temp = b; + b = b * ((double)(i + i) / x) - a; + a = temp; + } + } else { + for (i = n - 1; i > 0; i--) { + temp = b; + b = b * ((double)(i + i) / x) - a; + a = temp; + if (b > 1.0e100) { + a /= b; + t /= b; + b = one; + } + } + } + b = (t * __k_j0f(fx) / b); + } + f = (float)b; +#if defined(__i386) && !defined(__amd64) + if (rp != fp_extended) + (void) __swapRP(rp); +#endif + return ((sgn)? -f : f); +} + +float +ynf(int n, float fx) +{ + double a, b, temp, x; + float f; + int i, sign, ix; +#if defined(__i386) && !defined(__amd64) + int rp; +#endif + + sign = 0; + if (n < 0) { + n = -n; + if (n & 1) + sign = 1; + } + if (n == 0) + return (y0f(fx)); + if (n == 1) + return ((sign)? -y1f(fx) : y1f(fx)); + + ix = *(int *)&fx; + if ((ix & ~0x80000000) > 0x7f800000) /* nan */ + return (fx * fx); + if (ix <= 0) { /* zero or negative */ + if ((ix << 1) == 0) + return (-onef / zerof); + return (zerof / zerof); + } + if (ix == 0x7f800000) /* +inf */ + return (zerof); + +#if defined(__i386) && !defined(__amd64) + rp = __swapRP(fp_extended); +#endif + a = __k_y0f(fx); + b = __k_y1f(fx); + x = (double)fx; + for (i = 1; i < n; i++) { + temp = b; + b *= (double)(i + i) / x; + if (b <= -DBL_MAX) + break; + b -= a; + a = temp; + } + f = (float)b; +#if defined(__i386) && !defined(__amd64) + if (rp != fp_extended) + (void) __swapRP(rp); +#endif + return ((sign)? -f : f); +} diff --git a/usr/src/lib/libm/common/R/cbrtf.c b/usr/src/lib/libm/common/R/cbrtf.c new file mode 100644 index 0000000000..ca00310791 --- /dev/null +++ b/usr/src/lib/libm/common/R/cbrtf.c @@ -0,0 +1,42 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak cbrtf = __cbrtf + +#include "libm.h" + +float +cbrtf(float x) { +#if defined(FPADD_TRAPS_INCOMPLETE_ON_NAN) + if (isnanf(x)) + return (x * x); + else +#endif + return ((float) cbrt((double) x)); +} diff --git a/usr/src/lib/libm/common/R/copysignf.c b/usr/src/lib/libm/common/R/copysignf.c new file mode 100644 index 0000000000..84ae2e31b4 --- /dev/null +++ b/usr/src/lib/libm/common/R/copysignf.c @@ -0,0 +1,42 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#if defined(ELFOBJ) +#pragma weak copysignf = __copysignf +#endif + +#include "libm.h" + +float +copysignf(float x, float y) { + float w; + + *(int *) &w = (*(int *) &x & ~0x80000000) | (*(int *) &y & 0x80000000); + return (w); +} diff --git a/usr/src/lib/libm/common/R/cosf.c b/usr/src/lib/libm/common/R/cosf.c new file mode 100644 index 0000000000..34b436be56 --- /dev/null +++ b/usr/src/lib/libm/common/R/cosf.c @@ -0,0 +1,148 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak cosf = __cosf + +/* + * See sincosf.c + */ + +#include "libm.h" + +extern const int _TBL_ipio2_inf[]; +extern int __rem_pio2m(double *, double *, int, int, int, const int *); +#if defined(__i386) && !defined(__amd64) +extern int __swapRP(int); +#endif + +static const double C[] = { + 1.85735322054308378716204874632872525989806770558e-0003, + -1.95035094218403635082921458859320791358115801259e-0004, + 5.38400550766074785970952495168558701485841707252e+0002, + -3.31975110777873728964197739157371509422022905947e+0001, + 1.09349482127188401868272000389539985058873853699e-0003, + -5.03324285989964979398034700054920226866107675091e-0004, + 2.43792880266971107750418061559602239831538067410e-0005, + 9.14499072605666582228127405245558035523741471271e+0002, + -3.63151270591815439197122504991683846785293207730e+0001, + 0.636619772367581343075535, /* 2^ -1 * 1.45F306DC9C883 */ + 0.5, + 1.570796326734125614166, /* 2^ 0 * 1.921FB54400000 */ + 6.077100506506192601475e-11, /* 2^-34 * 1.0B4611A626331 */ +}; + +#define S0 C[0] +#define S1 C[1] +#define S2 C[2] +#define S3 C[3] +#define C0 C[4] +#define C1 C[5] +#define C2 C[6] +#define C3 C[7] +#define C4 C[8] +#define invpio2 C[9] +#define half C[10] +#define pio2_1 C[11] +#define pio2_t C[12] + +float +cosf(float x) +{ + double y, z, w; + float f; + int n, ix, hx, hy; + volatile int i; + + hx = *((int *)&x); + ix = hx & 0x7fffffff; + + y = (double)x; + + if (ix <= 0x4016cbe4) { /* |x| < 3*pi/4 */ + if (ix <= 0x3f490fdb) { /* |x| < pi/4 */ + if (ix <= 0x39800000) { /* |x| <= 2**-12 */ + i = (int)y; +#ifdef lint + i = i; +#endif + return (1.0f); + } + z = y * y; + return ((float)(((C0 + z * C1) + (z * z) * C2) * + (C3 + z * (C4 + z)))); + } else if (hx > 0) { + y = (y - pio2_1) - pio2_t; + z = y * y; + return ((float)-((y * (S0 + z * S1)) * + (S2 + z * (S3 + z)))); + } else { + y = (y + pio2_1) + pio2_t; + z = y * y; + return ((float)((y * (S0 + z * S1)) * + (S2 + z * (S3 + z)))); + } + } else if (ix <= 0x49c90fdb) { /* |x| < 2^19*pi */ +#if defined(__i386) && !defined(__amd64) + int rp; + + rp = __swapRP(fp_extended); +#endif + w = y * invpio2; + if (hx < 0) + n = (int)(w - half); + else + n = (int)(w + half); + y = (y - n * pio2_1) - n * pio2_t; + n++; +#if defined(__i386) && !defined(__amd64) + if (rp != fp_extended) + (void) __swapRP(rp); +#endif + } else { + if (ix >= 0x7f800000) + return (x / x); /* cos(Inf or NaN) is NaN */ + hy = ((int *)&y)[HIWORD]; + n = ((hy >> 20) & 0x7ff) - 1046; + ((int *)&w)[HIWORD] = (hy & 0xfffff) | 0x41600000; + ((int *)&w)[LOWORD] = ((int *)&y)[LOWORD]; + n = __rem_pio2m(&w, &y, n, 1, 0, _TBL_ipio2_inf) + 1; + } + + if (n & 1) { + /* compute cos y */ + z = y * y; + f = (float)(((C0 + z * C1) + (z * z) * C2) * + (C3 + z * (C4 + z))); + } else { + /* compute sin y */ + z = y * y; + f = (float)((y * (S0 + z * S1)) * (S2 + z * (S3 + z))); + } + + return ((n & 2)? -f : f); +} diff --git a/usr/src/lib/libm/common/R/coshf.c b/usr/src/lib/libm/common/R/coshf.c new file mode 100644 index 0000000000..0c715f6fcf --- /dev/null +++ b/usr/src/lib/libm/common/R/coshf.c @@ -0,0 +1,50 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak coshf = __coshf + +#include "libm.h" + +float +coshf(float x) { + double c; + float w; + int ix; + + ix = *(int *)&x & ~0x80000000; + if (ix >= 0x7f800000) { + /* coshf(x) is |x| if x is +-Inf or NaN */ + return (x * x); + } + if (ix >= 0x43000000) /* coshf(x) trivially overflows */ + c = 1.0e100; + else + c = cosh((double)x); + w = (float)c; + return (w); +} diff --git a/usr/src/lib/libm/common/R/erff.c b/usr/src/lib/libm/common/R/erff.c new file mode 100644 index 0000000000..ae58e3477e --- /dev/null +++ b/usr/src/lib/libm/common/R/erff.c @@ -0,0 +1,69 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak erff = __erff +#pragma weak erfcf = __erfcf + +#include "libm.h" + +#if defined(__i386) && !defined(__amd64) +extern int __swapRP(int); +#endif + +float +erff(float x) { + int ix; + + ix = *(int *)&x & ~0x80000000; + if (ix > 0x7f800000) /* x is NaN */ + return (x * x); + return ((float)erf((double)x)); +} + +float +erfcf(float x) { + float f; + int ix; +#if defined(__i386) && !defined(__amd64) + int rp; +#endif + + ix = *(int *)&x & ~0x80000000; + if (ix > 0x7f800000) /* x is NaN */ + return (x * x); + +#if defined(__i386) && !defined(__amd64) + rp = __swapRP(fp_extended); +#endif + f = (float)erfc((double)x); +#if defined(__i386) && !defined(__amd64) + if (rp != fp_extended) + (void) __swapRP(rp); +#endif + return (f); +} diff --git a/usr/src/lib/libm/common/R/exp10f.c b/usr/src/lib/libm/common/R/exp10f.c new file mode 100644 index 0000000000..b402899a0d --- /dev/null +++ b/usr/src/lib/libm/common/R/exp10f.c @@ -0,0 +1,44 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak exp10f = __exp10f + +#include "libm.h" + +extern double exp10(double); + +float +exp10f(float x) { +#if defined(FPADD_TRAPS_INCOMPLETE_ON_NAN) + if (isnanf(x)) + return (x * x); + else +#endif + return ((float) exp10((double) x)); +} diff --git a/usr/src/lib/libm/common/R/exp2f.c b/usr/src/lib/libm/common/R/exp2f.c new file mode 100644 index 0000000000..61d6d133d6 --- /dev/null +++ b/usr/src/lib/libm/common/R/exp2f.c @@ -0,0 +1,42 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak exp2f = __exp2f + +#include "libm.h" + +float +exp2f(float x) { +#if defined(FPADD_TRAPS_INCOMPLETE_ON_NAN) + if (isnanf(x)) + return (x * x); + else +#endif + return ((float) exp2((double) x)); +} diff --git a/usr/src/lib/libm/common/R/expf.c b/usr/src/lib/libm/common/R/expf.c new file mode 100644 index 0000000000..179612aa7c --- /dev/null +++ b/usr/src/lib/libm/common/R/expf.c @@ -0,0 +1,401 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak expf = __expf + +/* INDENT OFF */ +/* + * float expf(float x); + * Code by K.C. Ng for SUN 5.0 libmopt + * 11/5/99 + * Method : + * 1. For |x| >= 2^7, either underflow/overflow. + * More precisely: + * x > 88.722839355...(0x42B17218) => overflow; + * x < -103.97207642..(0xc2CFF1B4) => underflow. + * 2. For |x| < 2^-6, use polynomail + * exp(x) = 1 + x + p1*x^2 + p2*x^3 + * 3. Otherwise, write |x|=(1+r)*2^n, where 0<=r<1. + * Let t = 2^n * (1+r) .... x > 0; + * t = 2^n * (1-r) .... x < 0. (x= -2**(n+1)+t) + * Since -6 <= n <= 6, we may break t into + * six 6-bits chunks: + * -5 -11 -17 -23 -29 + * t=j *2+j *2 +j *2 +j *2 +j *2 +j *2 + * 1 2 3 4 5 6 + * + * where 0 <= j < 64 for i = 1,...,6. + * i + * Note that since t has only 24 significant bits, + * either j or j must be 0. + * 1 6 + * 7-6i + * One may define j by (int) ( t * 2 ) mod 64 + * i + * mathematically. In actual implementation, they can + * be obtained by manipulating the exponent and + * mantissa bits as follow: + * Let ix = (HEX(x)&0x007fffff)|0x00800000. + * If n>=0, let ix=ix<<n, then j =0 and + * 6 + * j = ix>>(30-6i)) mod 64 ...i=1,...,5 + * i + * Otherwise, let ix=ix<<(j+6), then j = 0 and + * 1 + * j = ix>>(36-6i)) mod 64 ...i=2,...,6 + * i + * + * 4. Compute exp(t) by table look-up method. + * Precompute ET[k] = exp(j*2^(7-6i)), k=j+64*(6-i). + * Then + * exp(t) = ET[j +320]*ET[j +256]*ET[j +192]* + * 1 2 3 + * + * ET[j +128]*ET[j +64]*ET[j ] + * 4 5 6 + * + * n+1 + * 5. If x < 0, return exp(-2 )* exp(t). Note that + * -6 <= n <= 6. Let k = n - 6, then we can + * precompute + * k-5 n+1 + * EN[k] = exp(-2 ) = exp(-2 ) for k=0,1,...,12. + * + * + * Special cases: + * exp(INF) is INF, exp(NaN) is NaN; + * exp(-INF) = 0; + * for finite argument, only exp(0) = 1 is exact. + * + * Accuracy: + * All calculations are done in double precision except for + * the case |x| < 2^-6. When |x| < 2^-6, the error is less + * than 0.55 ulp. When |x| >= 2^-6 and the result is normal, + * the error is less than 0.51 ulp. When FDTOS_TRAPS_... is + * defined and the result is subnormal, the error can be as + * large as 0.75 ulp. + */ +/* INDENT ON */ + +#include "libm.h" + +/* + * ET[k] = exp(j*2^(7-6i)) , where j = k mod 64, i = k/64 + */ +static const double ET[] = { + 1.00000000000000000000e+00, 1.00000000186264514923e+00, + 1.00000000372529029846e+00, 1.00000000558793544769e+00, + 1.00000000745058059692e+00, 1.00000000931322574615e+00, + 1.00000001117587089539e+00, 1.00000001303851604462e+00, + 1.00000001490116119385e+00, 1.00000001676380656512e+00, + 1.00000001862645171435e+00, 1.00000002048909686359e+00, + 1.00000002235174201282e+00, 1.00000002421438716205e+00, + 1.00000002607703253332e+00, 1.00000002793967768255e+00, + 1.00000002980232283178e+00, 1.00000003166496798102e+00, + 1.00000003352761335229e+00, 1.00000003539025850152e+00, + 1.00000003725290365075e+00, 1.00000003911554879998e+00, + 1.00000004097819417126e+00, 1.00000004284083932049e+00, + 1.00000004470348446972e+00, 1.00000004656612984100e+00, + 1.00000004842877499023e+00, 1.00000005029142036150e+00, + 1.00000005215406551073e+00, 1.00000005401671088201e+00, + 1.00000005587935603124e+00, 1.00000005774200140252e+00, + 1.00000005960464655175e+00, 1.00000006146729192302e+00, + 1.00000006332993707225e+00, 1.00000006519258244353e+00, + 1.00000006705522759276e+00, 1.00000006891787296404e+00, + 1.00000007078051811327e+00, 1.00000007264316348454e+00, + 1.00000007450580863377e+00, 1.00000007636845400505e+00, + 1.00000007823109937632e+00, 1.00000008009374452556e+00, + 1.00000008195638989683e+00, 1.00000008381903526811e+00, + 1.00000008568168063938e+00, 1.00000008754432578861e+00, + 1.00000008940697115989e+00, 1.00000009126961653116e+00, + 1.00000009313226190244e+00, 1.00000009499490705167e+00, + 1.00000009685755242295e+00, 1.00000009872019779422e+00, + 1.00000010058284316550e+00, 1.00000010244548853677e+00, + 1.00000010430813368600e+00, 1.00000010617077905728e+00, + 1.00000010803342442856e+00, 1.00000010989606979983e+00, + 1.00000011175871517111e+00, 1.00000011362136054238e+00, + 1.00000011548400591366e+00, 1.00000011734665128493e+00, + 1.00000000000000000000e+00, 1.00000011920929665621e+00, + 1.00000023841860752327e+00, 1.00000035762793260119e+00, + 1.00000047683727188996e+00, 1.00000059604662538959e+00, + 1.00000071525599310007e+00, 1.00000083446537502141e+00, + 1.00000095367477115360e+00, 1.00000107288418149665e+00, + 1.00000119209360605055e+00, 1.00000131130304481530e+00, + 1.00000143051249779091e+00, 1.00000154972196497738e+00, + 1.00000166893144637470e+00, 1.00000178814094198287e+00, + 1.00000190735045180190e+00, 1.00000202655997583179e+00, + 1.00000214576951407253e+00, 1.00000226497906652412e+00, + 1.00000238418863318657e+00, 1.00000250339821405987e+00, + 1.00000262260780914403e+00, 1.00000274181741843904e+00, + 1.00000286102704194491e+00, 1.00000298023667966163e+00, + 1.00000309944633158921e+00, 1.00000321865599772764e+00, + 1.00000333786567807692e+00, 1.00000345707537263706e+00, + 1.00000357628508140806e+00, 1.00000369549480438991e+00, + 1.00000381470454158261e+00, 1.00000393391429298617e+00, + 1.00000405312405860059e+00, 1.00000417233383842586e+00, + 1.00000429154363246198e+00, 1.00000441075344070896e+00, + 1.00000452996326316679e+00, 1.00000464917309983548e+00, + 1.00000476838295071502e+00, 1.00000488759281580542e+00, + 1.00000500680269510667e+00, 1.00000512601258861878e+00, + 1.00000524522249634174e+00, 1.00000536443241827556e+00, + 1.00000548364235442023e+00, 1.00000560285230477575e+00, + 1.00000572206226934213e+00, 1.00000584127224811937e+00, + 1.00000596048224110746e+00, 1.00000607969224830640e+00, + 1.00000619890226971620e+00, 1.00000631811230533685e+00, + 1.00000643732235516836e+00, 1.00000655653241921073e+00, + 1.00000667574249746394e+00, 1.00000679495258992802e+00, + 1.00000691416269660294e+00, 1.00000703337281748873e+00, + 1.00000715258295258536e+00, 1.00000727179310189285e+00, + 1.00000739100326541120e+00, 1.00000751021344314040e+00, + 1.00000000000000000000e+00, 1.00000762942363508046e+00, + 1.00001525890547848796e+00, 1.00002288844553022251e+00, + 1.00003051804379095024e+00, 1.00003814770026133729e+00, + 1.00004577741494138365e+00, 1.00005340718783175546e+00, + 1.00006103701893311886e+00, 1.00006866690824547383e+00, + 1.00007629685576948653e+00, 1.00008392686150582307e+00, + 1.00009155692545448346e+00, 1.00009918704761613384e+00, + 1.00010681722799144033e+00, 1.00011444746658040295e+00, + 1.00012207776338368781e+00, 1.00012970811840196106e+00, + 1.00013733853163522269e+00, 1.00014496900308413885e+00, + 1.00015259953274937565e+00, 1.00016023012063093311e+00, + 1.00016786076672947736e+00, 1.00017549147104567453e+00, + 1.00018312223357952462e+00, 1.00019075305433191581e+00, + 1.00019838393330284809e+00, 1.00020601487049298761e+00, + 1.00021364586590300050e+00, 1.00022127691953288675e+00, + 1.00022890803138353455e+00, 1.00023653920145494389e+00, + 1.00024417042974778091e+00, 1.00025180171626271175e+00, + 1.00025943306099973640e+00, 1.00026706446395974304e+00, + 1.00027469592514273167e+00, 1.00028232744454959047e+00, + 1.00028995902218031944e+00, 1.00029759065803558471e+00, + 1.00030522235211605242e+00, 1.00031285410442172257e+00, + 1.00032048591495348333e+00, 1.00032811778371155675e+00, + 1.00033574971069616488e+00, 1.00034338169590819589e+00, + 1.00035101373934764979e+00, 1.00035864584101541475e+00, + 1.00036627800091149076e+00, 1.00037391021903676602e+00, + 1.00038154249539146257e+00, 1.00038917482997580244e+00, + 1.00039680722279067382e+00, 1.00040443967383629875e+00, + 1.00041207218311289928e+00, 1.00041970475062136359e+00, + 1.00042733737636191371e+00, 1.00043497006033499375e+00, + 1.00044260280254104778e+00, 1.00045023560298029786e+00, + 1.00045786846165363215e+00, 1.00046550137856127272e+00, + 1.00047313435370366363e+00, 1.00048076738708124900e+00, + 1.00000000000000000000e+00, 1.00048840047869447289e+00, + 1.00097703949241645383e+00, 1.00146591715766675179e+00, + 1.00195503359100279717e+00, 1.00244438890903908579e+00, + 1.00293398322844673487e+00, 1.00342381666595459322e+00, + 1.00391388933834746489e+00, 1.00440420136246855165e+00, + 1.00489475285521656645e+00, 1.00538554393354861993e+00, + 1.00587657471447822211e+00, 1.00636784531507639251e+00, + 1.00685935585247099411e+00, 1.00735110644384739942e+00, + 1.00784309720644804642e+00, 1.00833532825757243856e+00, + 1.00882779971457803292e+00, 1.00932051169487890796e+00, + 1.00981346431594687374e+00, 1.01030665769531102782e+00, + 1.01080009195055753324e+00, 1.01129376719933050666e+00, + 1.01178768355933157430e+00, 1.01228184114831898377e+00, + 1.01277624008410960244e+00, 1.01327088048457714109e+00, + 1.01376576246765282008e+00, 1.01426088615132625748e+00, + 1.01475625165364347069e+00, 1.01525185909270931894e+00, + 1.01574770858668572693e+00, 1.01624380025379235093e+00, + 1.01674013421230657883e+00, 1.01723671058056375216e+00, + 1.01773352947695694404e+00, 1.01823059101993673714e+00, + 1.01872789532801233392e+00, 1.01922544251975000229e+00, + 1.01972323271377418585e+00, 1.02022126602876750390e+00, + 1.02071954258347008526e+00, 1.02121806249668067856e+00, + 1.02171682588725554197e+00, 1.02221583287410910934e+00, + 1.02271508357621376817e+00, 1.02321457811260052573e+00, + 1.02371431660235789884e+00, 1.02421429916463280207e+00, + 1.02471452591863054771e+00, 1.02521499698361440167e+00, + 1.02571571247890602763e+00, 1.02621667252388526492e+00, + 1.02671787723799012859e+00, 1.02721932674071725344e+00, + 1.02772102115162167202e+00, 1.02822296059031659254e+00, + 1.02872514517647339893e+00, 1.02922757502982276101e+00, + 1.02973025027015285815e+00, 1.03023317101731093359e+00, + 1.03073633739120262831e+00, 1.03123974951179242510e+00, + 1.00000000000000000000e+00, 1.03174340749910276038e+00, + 1.06449445891785954288e+00, 1.09828514030782575794e+00, + 1.13314845306682632220e+00, 1.16911844616950433284e+00, + 1.20623024942098067136e+00, 1.24452010776609522935e+00, + 1.28402541668774139438e+00, 1.32478475872886569675e+00, + 1.36683794117379631139e+00, 1.41022603492571074746e+00, + 1.45499141461820125087e+00, 1.50117780000012279729e+00, + 1.54883029863413312910e+00, 1.59799544995063325104e+00, + 1.64872127070012819416e+00, 1.70105730184840076014e+00, + 1.75505465696029849809e+00, 1.81076607211938722664e+00, + 1.86824595743222232613e+00, 1.92755045016754467113e+00, + 1.98873746958229191684e+00, 2.05186677348797674725e+00, + 2.11700001661267478426e+00, 2.18420081081561789915e+00, + 2.25353478721320854561e+00, 2.32506966027712103084e+00, + 2.39887529396709808793e+00, 2.47502376996302508871e+00, + 2.55358945806292680913e+00, 2.63464908881563086851e+00, + 2.71828182845904553488e+00, 2.80456935623722669604e+00, + 2.89359594417176113623e+00, 2.98544853936535581340e+00, + 3.08021684891803104733e+00, 3.17799342753883840018e+00, + 3.27887376793867346692e+00, 3.38295639409246895468e+00, + 3.49034295746184142217e+00, 3.60113833627217561073e+00, + 3.71545073794110392029e+00, 3.83339180475841034834e+00, + 3.95507672292057721464e+00, 4.08062433502646015882e+00, + 4.21015725614395996956e+00, 4.34380199356104235164e+00, + 4.48168907033806451778e+00, 4.62395315278208052234e+00, + 4.77073318196760265408e+00, 4.92217250943229078786e+00, + 5.07841903718008147450e+00, 5.23962536212848917216e+00, + 5.40594892514116676097e+00, 5.57755216479125959239e+00, + 5.75460267600573072144e+00, 5.93727337374560715233e+00, + 6.12574266188198635064e+00, 6.32019460743274397174e+00, + 6.52081912033011246166e+00, 6.72781213889469142941e+00, + 6.94137582119703555605e+00, 7.16171874249371143151e+00, + 1.00000000000000000000e+00, 7.38905609893065040694e+00, + 5.45981500331442362040e+01, 4.03428793492735110249e+02, + 2.98095798704172830185e+03, 2.20264657948067178950e+04, + 1.62754791419003915507e+05, 1.20260428416477679275e+06, + 8.88611052050787210464e+06, 6.56599691373305097222e+07, + 4.85165195409790277481e+08, 3.58491284613159179688e+09, + 2.64891221298434715271e+10, 1.95729609428838775635e+11, + 1.44625706429147509766e+12, 1.06864745815244628906e+13, + 7.89629601826806875000e+13, 5.83461742527454875000e+14, + 4.31123154711519500000e+15, 3.18559317571137560000e+16, + 2.35385266837020000000e+17, 1.73927494152050099200e+18, + 1.28516001143593082880e+19, 9.49611942060244828160e+19, + 7.01673591209763143680e+20, 5.18470552858707204506e+21, + 3.83100800071657691546e+22, 2.83075330327469394756e+23, + 2.09165949601299610311e+24, 1.54553893559010391826e+25, + 1.14200738981568423454e+26, 8.43835666874145383188e+26, + 6.23514908081161674391e+27, 4.60718663433129178064e+28, + 3.40427604993174075827e+29, 2.51543867091916687979e+30, + 1.85867174528412788702e+31, 1.37338297954017610775e+32, + 1.01480038811388874615e+33, 7.49841699699012090701e+33, + 5.54062238439350983445e+34, 4.09399696212745451138e+35, + 3.02507732220114256223e+36, 2.23524660373471497416e+37, + 1.65163625499400180987e+38, 1.22040329431784083418e+39, + 9.01762840503429851945e+39, 6.66317621641089618500e+40, + 4.92345828601205826106e+41, 3.63797094760880474988e+42, + 2.68811714181613560943e+43, 1.98626483613765434356e+44, + 1.46766223015544238535e+45, 1.08446385529002313207e+46, + 8.01316426400059069850e+46, 5.92097202766466993617e+47, + 4.37503944726134096988e+48, 3.23274119108485947460e+49, + 2.38869060142499127023e+50, 1.76501688569176554670e+51, + 1.30418087839363225614e+52, 9.63666567360320166416e+52, + 7.12058632688933793173e+53, 5.26144118266638596909e+54, +}; + +/* + * EN[k] = exp(-2^(k-5)) + */ +static const double EN[] = { + 9.69233234476344129860e-01, 9.39413062813475807644e-01, + 8.82496902584595455110e-01, 7.78800783071404878477e-01, + 6.06530659712633424263e-01, 3.67879441171442334024e-01, + 1.35335283236612702318e-01, 1.83156388887341786686e-02, + 3.35462627902511853224e-04, 1.12535174719259116458e-07, + 1.26641655490941755372e-14, 1.60381089054863792659e-28, +#if defined(FDTOS_TRAPS_INCOMPLETE_IN_FNS_MODE) + 2.96555550007072683578e-38, /* exp(-128) scaled up by 2^60 */ +#else + 2.57220937264241481170e-56, +#endif +}; + +static const float F[] = { + 0.0f, + 1.0f, + 5.0000000951292138e-01F, + 1.6666518897347284e-01F, + 3.4028234663852885981170E+38F, + 1.1754943508222875079688E-38F, +#if defined(FDTOS_TRAPS_INCOMPLETE_IN_FNS_MODE) + 8.67361737988403547205962240695953369140625e-19F +#endif +}; + +#define zero F[0] +#define one F[1] +#define p1 F[2] +#define p2 F[3] +#define big F[4] +#define tiny F[5] +#if defined(FDTOS_TRAPS_INCOMPLETE_IN_FNS_MODE) +#define twom60 F[6] +#endif + +float +expf(float xf) { + double w, p, q; + int hx, ix, n; + + hx = *(int *)&xf; + ix = hx & ~0x80000000; + + if (ix < 0x3c800000) { /* |x| < 2**-6 */ + if (ix < 0x38800000) /* |x| < 2**-14 */ + return (one + xf); + return (one + (xf + (xf * xf) * (p1 + xf * p2))); + } + + n = ix >> 23; /* biased exponent */ + + if (n >= 0x86) { /* |x| >= 2^7 */ + if (n >= 0xff) { /* x is nan of +-inf */ + if (hx == 0xff800000) + return (zero); /* exp(-inf)=0 */ + return (xf * xf); /* exp(nan/inf) is nan or inf */ + } + if (hx > 0) + return (big * big); /* overflow */ + else + return (tiny * tiny); /* underflow */ + } + + ix -= n << 23; + if (hx > 0) + ix += 0x800000; + else + ix = 0x800000 - ix; + if (n >= 0x7f) { /* n >= 0 */ + ix <<= n - 0x7f; + w = ET[(ix & 0x3f) + 64] * ET[((ix >> 6) & 0x3f) + 128]; + p = ET[((ix >> 12) & 0x3f) + 192] * + ET[((ix >> 18) & 0x3f) + 256]; + q = ET[((ix >> 24) & 0x3f) + 320]; + } else { + ix <<= n - 0x79; + w = ET[ix & 0x3f] * ET[((ix >> 6) & 0x3f) + 64]; + p = ET[((ix >> 12) & 0x3f) + 128] * + ET[((ix >> 18) & 0x3f) + 192]; + q = ET[((ix >> 24) & 0x3f) + 256]; + } + xf = (float)((w * p) * (hx < 0 ? q * EN[n - 0x79] : q)); +#if defined(FDTOS_TRAPS_INCOMPLETE_IN_FNS_MODE) + if ((unsigned)hx >= 0xc2800000u) { + if ((unsigned)hx >= 0xc2aeac50) { /* force underflow */ + volatile float t = tiny; + t *= t; + } + return (xf * twom60); + } +#endif + return (xf); +} diff --git a/usr/src/lib/libm/common/R/expm1f.c b/usr/src/lib/libm/common/R/expm1f.c new file mode 100644 index 0000000000..6643a2000a --- /dev/null +++ b/usr/src/lib/libm/common/R/expm1f.c @@ -0,0 +1,42 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak expm1f = __expm1f + +#include "libm.h" + +float +expm1f(float x) { +#if defined(FPADD_TRAPS_INCOMPLETE_ON_NAN) + if (isnanf(x)) + return (x * x); + else +#endif + return ((float) expm1((double) x)); +} diff --git a/usr/src/lib/libm/common/R/fabsf.c b/usr/src/lib/libm/common/R/fabsf.c new file mode 100644 index 0000000000..40eb86b6db --- /dev/null +++ b/usr/src/lib/libm/common/R/fabsf.c @@ -0,0 +1,38 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak fabsf = __fabsf + +#include "libm.h" + +float +fabsf(float x) { + *(int *) &x &= ~0x80000000; + return (x); +} diff --git a/usr/src/lib/libm/common/R/floorf.c b/usr/src/lib/libm/common/R/floorf.c new file mode 100644 index 0000000000..f1c3c93f3d --- /dev/null +++ b/usr/src/lib/libm/common/R/floorf.c @@ -0,0 +1,111 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak ceilf = __ceilf +#pragma weak floorf = __floorf + +/* INDENT OFF */ +/* + * ceilf(x) return the biggest integral value (in float) below x + * floorf(x) return the least integral value (in float) above x + * + * NOTE: ceilf(x) and floorf(x) return result + * with the same sign as x's, including 0.0F. + */ + +#include "libm.h" + +static const float xf[] = { +/* ZEROF */ 0.0f, +/* ONEF */ 1.0f, +/* MONEF */ -1.0f, +/* HUGEF */ 1.0e30f, +}; + +#define ZEROF xf[0] +#define ONEF xf[1] +#define MONEF xf[2] +#define HUGEF xf[3] +/* INDENT ON */ + +float +ceilf(float x) { + volatile float dummy; + int hx, k, j, ix; + + hx = *(int *) &x; + ix = hx & ~0x80000000; + k = ix >> 23; + if (((k - 127) ^ (k - 150)) < 0) { + k = (1 << (150 - k)) - 1; + if ((k & hx) != 0) + dummy = HUGEF + x; /* raise inexact */ + j = k & (~(hx >> 31)); + *(int *) &x = (hx + j) & ~k; + return (x); + } else if (k <= 126) { + dummy = HUGEF + x; + if (hx > 0) + return (ONEF); + else if (ix == 0) + return (x); + else + return (-ZEROF); + } else + /* signal invalid if x is a SNaN */ + return (x * ONEF); /* +0 -> *1 for Cheetah */ +} + +float +floorf(float x) { + volatile float dummy; + int hx, k, j, ix; + + hx = *(int *) &x; + ix = hx & ~0x80000000; + k = ix >> 23; + if (((k - 127) ^ (k - 150)) < 0) { + k = (1 << (150 - k)) - 1; + if ((k & hx) != 0) + dummy = HUGEF + x; /* raise inexact */ + j = k & (hx >> 31); + *(int *) &x = (hx + j) & ~k; + return (x); + } else if (k <= 126) { + dummy = HUGEF + x; + if (hx > 0) + return (ZEROF); + else if (ix == 0) + return (x); + else + return (MONEF); + } else + /* signal invalid if x is a SNaN */ + return (x * ONEF); /* +0 -> *1 for Cheetah */ +} diff --git a/usr/src/lib/libm/common/R/fmodf.c b/usr/src/lib/libm/common/R/fmodf.c new file mode 100644 index 0000000000..d19bb3f2f8 --- /dev/null +++ b/usr/src/lib/libm/common/R/fmodf.c @@ -0,0 +1,176 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak fmodf = __fmodf + +#include "libm.h" + +/* INDENT OFF */ +static const int + is = (int)0x80000000, + im = 0x007fffff, + ii = 0x7f800000, + iu = 0x00800000; +/* INDENT ON */ + +static const float zero = 0.0; + +float +fmodf(float x, float y) { + float w; + int hx, ix, iy, iz, k, ny, nd; + + hx = *(int *)&x; + ix = hx & 0x7fffffff; + iy = *(int *)&y & 0x7fffffff; + + /* purge off exception values */ + if (ix >= ii || iy > ii || iy == 0) { + w = x * y; + w = w / w; + } else if (ix <= iy) { + if (ix < iy) + w = x; /* return x if |x|<|y| */ + else + w = zero * x; /* return sign(x)*0.0 */ + } else { + /* INDENT OFF */ + /* + * scale x,y to "normal" with + * ny = exponent of y + * nd = exponent of x minus exponent of y + */ + /* INDENT ON */ + ny = iy >> 23; + k = ix >> 23; + + /* special case for subnormal y or x */ + if (ny == 0) { + ny = 1; + while (iy < iu) { + ny -= 1; + iy += iy; + } + nd = k - ny; + if (k == 0) { + nd += 1; + while (ix < iu) { + nd -= 1; + ix += ix; + } + } else { + ix = iu | (ix & im); + } + } else { + nd = k - ny; + ix = iu | (ix & im); + iy = iu | (iy & im); + } + + /* fix point fmod for normalized ix and iy */ + /* INDENT OFF */ + /* + * while (nd--) { + * iz = ix - iy; + * if (iz < 0) + * ix = ix + ix; + * else if (iz == 0) { + * *(int *) &w = is & hx; + * return w; + * } + * else + * ix = iz + iz; + * } + */ + /* INDENT ON */ + /* unroll the above loop 4 times to gain performance */ + k = nd >> 2; + nd -= k << 2; + while (k--) { + iz = ix - iy; + if (iz >= 0) + ix = iz + iz; + else + ix += ix; + iz = ix - iy; + if (iz >= 0) + ix = iz + iz; + else + ix += ix; + iz = ix - iy; + if (iz >= 0) + ix = iz + iz; + else + ix += ix; + iz = ix - iy; + if (iz >= 0) + ix = iz + iz; + else + ix += ix; + if (iz == 0) { + *(int *)&w = is & hx; + return (w); + } + } + while (nd--) { + iz = ix - iy; + if (iz >= 0) + ix = iz + iz; + else + ix += ix; + } + /* end of unrolling */ + + iz = ix - iy; + if (iz >= 0) + ix = iz; + + /* convert back to floating value and restore the sign */ + if (ix == 0) { + *(int *)&w = is & hx; + return (w); + } + while (ix < iu) { + ix += ix; + ny -= 1; + } + while (ix > (iu + iu)) { + ny += 1; + ix >>= 1; + } + if (ny > 0) { + *(int *)&w = (is & hx) | (ix & im) | (ny << 23); + } else { + /* subnormal output */ + k = -ny + 1; + ix >>= k; + *(int *)&w = (is & hx) | ix; + } + } + return (w); +} diff --git a/usr/src/lib/libm/common/R/gammaf.c b/usr/src/lib/libm/common/R/gammaf.c new file mode 100644 index 0000000000..89a6a6f406 --- /dev/null +++ b/usr/src/lib/libm/common/R/gammaf.c @@ -0,0 +1,36 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak gammaf = __gammaf + +#include "libm.h" + +float +gammaf(float x) { + return (lgammaf(x)); +} diff --git a/usr/src/lib/libm/common/R/gammaf_r.c b/usr/src/lib/libm/common/R/gammaf_r.c new file mode 100644 index 0000000000..4a1c317c4b --- /dev/null +++ b/usr/src/lib/libm/common/R/gammaf_r.c @@ -0,0 +1,36 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak gammaf_r = __gammaf_r + +#include "libm.h" + +float +gammaf_r(float x, int *signgamfp) { + return (lgammaf_r(x, signgamfp)); +} diff --git a/usr/src/lib/libm/common/R/hypotf.c b/usr/src/lib/libm/common/R/hypotf.c new file mode 100644 index 0000000000..87729c5344 --- /dev/null +++ b/usr/src/lib/libm/common/R/hypotf.c @@ -0,0 +1,64 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak hypotf = __hypotf + +#include "libm.h" + +float +hypotf(float x, float y) { + double dx, dy; + float w; + int ix, iy; + + ix = (*(int *) &x) & 0x7fffffff; + iy = (*(int *) &y) & 0x7fffffff; + if (ix >= 0x7f800000) { + if (ix == 0x7f800000) + *(int *) &w = x == y ? iy : ix; /* w = |x| = inf */ + else if (iy == 0x7f800000) + *(int *) &w = x == y ? ix : iy; /* w = |y| = inf */ + else + w = fabsf(x) * fabsf(y); /* + -> * for Cheetah */ + } else if (iy >= 0x7f800000) { + if (iy == 0x7f800000) + *(int *) &w = x == y ? ix : iy; /* w = |y| = inf */ + else + w = fabsf(x) * fabsf(y); /* + -> * for Cheetah */ + } else if (ix == 0) + *(int *) &w = iy; /* w = |y| */ + else if (iy == 0) + *(int *) &w = ix; /* w = |x| */ + else { + dx = (double) x; + dy = (double) y; + w = (float) sqrt(dx * dx + dy * dy); + } + return (w); +} diff --git a/usr/src/lib/libm/common/R/ilogbf.c b/usr/src/lib/libm/common/R/ilogbf.c new file mode 100644 index 0000000000..2579d024ed --- /dev/null +++ b/usr/src/lib/libm/common/R/ilogbf.c @@ -0,0 +1,90 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#if defined(ELFOBJ) +#pragma weak ilogbf = __ilogbf +#endif + +#include "libm.h" +#include "xpg6.h" /* __xpg6 */ + +#if defined(USE_FPSCALE) || defined(__x86) +static const float two25 = 33554432.0F; +#else +/* + * v: a non-zero subnormal |x| + */ +static int +ilogbf_subnormal(unsigned v) { + int r = -126 - 23; + + if (v & 0xffff0000) + r += 16, v >>= 16; + if (v & 0xff00) + r += 8, v >>= 8; + if (v & 0xf0) + r += 4, v >>= 4; + v <<= 1; + return (r + ((0xffffaa50 >> v) & 0x3)); +} +#endif /* defined(USE_FPSCALE) */ + +static int +raise_invalid(int v) { /* SUSv3 requires ilogbf(0,+/-Inf,NaN) raise invalid */ +#ifndef lint + if ((__xpg6 & _C99SUSv3_ilogb_0InfNaN_raises_invalid) != 0) { + static const double zero = 0.0; + volatile double dummy; + + dummy = zero / zero; + } +#endif + return (v); +} + +int +ilogbf(float x) { + int k = *((int *) &x) & ~0x80000000; + + if (k < 0x00800000) { + if (k == 0) + return (raise_invalid(0x80000001)); + else { +#if defined(USE_FPSCALE) || defined(__x86) + x *= two25; + return (((*((int *) &x) & 0x7f800000) >> 23) - 152); +#else + return (ilogbf_subnormal(k)); +#endif + } + } else if (k < 0x7f800000) + return ((k >> 23) - 127); + else + return (raise_invalid(0x7fffffff)); +} diff --git a/usr/src/lib/libm/common/R/isnanf.c b/usr/src/lib/libm/common/R/isnanf.c new file mode 100644 index 0000000000..b2dd090a19 --- /dev/null +++ b/usr/src/lib/libm/common/R/isnanf.c @@ -0,0 +1,40 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#if defined(ELFOBJ) +#pragma weak isnanf = __isnanf +#pragma weak _isnanf = __isnanf +#endif + +#include "libm.h" + +int +isnanf(float x) { + return ((*(int *) &x & ~0x80000000) > 0x7f800000); +} diff --git a/usr/src/lib/libm/common/R/lgammaf.c b/usr/src/lib/libm/common/R/lgammaf.c new file mode 100644 index 0000000000..bcc4ea03a7 --- /dev/null +++ b/usr/src/lib/libm/common/R/lgammaf.c @@ -0,0 +1,44 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak lgammaf = __lgammaf + +#include "libm.h" + +extern int signgamf; + +float +lgammaf(float x) { + float y; + + if (isnanf(x)) + return (x * x); + y = (float)__k_lgamma((double)x, &signgamf); + signgam = signgamf; /* SUSv3 requires the setting of signgam */ + return (y); +} diff --git a/usr/src/lib/libm/common/R/lgammaf_r.c b/usr/src/lib/libm/common/R/lgammaf_r.c new file mode 100644 index 0000000000..1c3cf27d2c --- /dev/null +++ b/usr/src/lib/libm/common/R/lgammaf_r.c @@ -0,0 +1,38 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak lgammaf_r = __lgammaf_r + +#include "libm.h" + +float +lgammaf_r(float x, int *signgamfp) { + if (isnanf(x)) + return (x * x); + return ((float)__k_lgamma((double)x, signgamfp)); +} diff --git a/usr/src/lib/libm/common/R/log10f.c b/usr/src/lib/libm/common/R/log10f.c new file mode 100644 index 0000000000..595ad9bf8b --- /dev/null +++ b/usr/src/lib/libm/common/R/log10f.c @@ -0,0 +1,55 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak log10f = __log10f + +#include "libm.h" + +static const float zero = 0.0f, mone = -1.0f; + +float +log10f(float x) { + int hx, ix; + float w; + + hx = *(int *)&x; + ix = hx & ~0x80000000; + if (ix > 0x7f800000) + return (x * x); + if (ix == 0x7f800000) + return (x + x * x); + if (ix == 0) { + w = mone; + return (w / zero); + } + if (hx < 0) { + w = zero; + return (w / zero); + } + return ((float)log10((double)x)); +} diff --git a/usr/src/lib/libm/common/R/log1pf.c b/usr/src/lib/libm/common/R/log1pf.c new file mode 100644 index 0000000000..0cb5b073e7 --- /dev/null +++ b/usr/src/lib/libm/common/R/log1pf.c @@ -0,0 +1,52 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak log1pf = __log1pf + +#include "libm.h" + +static const float zero = 0.0f; + +float +log1pf(float x) { + int ix; + + ix = *(int *)&x; + if (ix >= 0x7f800000) { + /* x is +inf or nan */ + return (x * x); + } + if (ix < 0) { + ix &= ~0x80000000; + if (ix == 0x3f800000) /* x is -1 */ + return (x / zero); + if (ix > 0x3f800000) /* x is < -1 or nan */ + return ((x * zero) / zero); + } + return ((float)log1p((double)x)); +} diff --git a/usr/src/lib/libm/common/R/log2f.c b/usr/src/lib/libm/common/R/log2f.c new file mode 100644 index 0000000000..cd168ffc3b --- /dev/null +++ b/usr/src/lib/libm/common/R/log2f.c @@ -0,0 +1,42 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak log2f = __log2f + +#include "libm.h" + +float +log2f(float x) { +#if defined(FPADD_TRAPS_INCOMPLETE_ON_NAN) + if (isnanf(x)) + return (x * x); + else +#endif + return ((float) log2((double) x)); +} diff --git a/usr/src/lib/libm/common/R/logbf.c b/usr/src/lib/libm/common/R/logbf.c new file mode 100644 index 0000000000..bf6851ef68 --- /dev/null +++ b/usr/src/lib/libm/common/R/logbf.c @@ -0,0 +1,87 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#if defined(ELFOBJ) +#pragma weak logbf = __logbf +#endif + +#include "libm.h" +#include "xpg6.h" /* __xpg6 */ +#define _C99SUSv3_logb _C99SUSv3_logb_subnormal_is_like_ilogb + +#if defined(USE_FPSCALE) || defined(__x86) +static const float two25 = 33554432.0F; +#else +/* + * v: a non-zero subnormal |x| + */ +static int +ilogbf_subnormal(unsigned v) { + int r = -126 - 23; + + if (v & 0xffff0000) + r += 16, v >>= 16; + if (v & 0xff00) + r += 8, v >>= 8; + if (v & 0xf0) + r += 4, v >>= 4; + v <<= 1; + return (r + ((0xffffaa50 >> v) & 0x3)); +} +#endif /* defined(USE_FPSCALE) */ + +static float +raise_division(float t) { +#pragma STDC FENV_ACCESS ON + static const float zero = 0.0F; + return (t / zero); +} + +float +logbf(float x) { + int k = *((int *) &x) & ~0x80000000; + + if (k < 0x00800000) { + if (k == 0) + return (raise_division(-1.0F)); + else if ((__xpg6 & _C99SUSv3_logb) != 0) { +#if defined(USE_FPSCALE) || defined(__x86) + x *= two25; + return ((float) (((*((int *) &x) & 0x7f800000) >> 23) - + 152)); +#else + return ((float) ilogbf_subnormal(k)); +#endif + } else + return (-126.F); + } else if (k < 0x7f800000) + return ((float) ((k >> 23) - 127)); + else + return (x * x); +} diff --git a/usr/src/lib/libm/common/R/logf.c b/usr/src/lib/libm/common/R/logf.c new file mode 100644 index 0000000000..d746260917 --- /dev/null +++ b/usr/src/lib/libm/common/R/logf.c @@ -0,0 +1,148 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak logf = __logf + +/* + * Algorithm: + * + * Let y = x rounded to six significant bits. Then for any choice + * of e and z such that y = 2^e z, we have + * + * log(x) = e log(2) + log(z) + log(1+(x-y)/y) + * + * Note that (x-y)/y = (x'-y')/y' for any scaled x' = sx, y' = sy; + * in particular, we can take s to be the power of two that makes + * ulp(x') = 1. + * + * From a table, obtain l = log(z) and r = 1/y'. For |s| <= 2^-6, + * approximate log(1+s) by a polynomial p(s) where p(s) := s+s*s* + * (K1+s*(K2+s*K3)). Then we compute the expression above as + * e*ln2 + l + p(r*(x'-y')) all evaluated in double precision. + * + * When x is subnormal, we first scale it to the normal range, + * adjusting e accordingly. + * + * Accuracy: + * + * The largest error is less than 0.6 ulps. + */ + +#include "libm.h" + +/* + * For i = 0, ..., 12, + * TBL[2i] = log(1 + i/32) and TBL[2i+1] = 2^-23 / (1 + i/32) + * + * For i = 13, ..., 32, + * TBL[2i] = log(1/2 + i/64) and TBL[2i+1] = 2^-23 / (1 + i/32) + */ +static const double TBL[] = { + 0.000000000000000000e+00, 1.192092895507812500e-07, + 3.077165866675368733e-02, 1.155968868371212153e-07, + 6.062462181643483994e-02, 1.121969784007352926e-07, + 8.961215868968713805e-02, 1.089913504464285680e-07, + 1.177830356563834557e-01, 1.059638129340277719e-07, + 1.451820098444978890e-01, 1.030999260979729787e-07, + 1.718502569266592284e-01, 1.003867701480263102e-07, + 1.978257433299198675e-01, 9.781275040064102225e-08, + 2.231435513142097649e-01, 9.536743164062500529e-08, + 2.478361639045812692e-01, 9.304139672256097884e-08, + 2.719337154836417580e-01, 9.082612537202380448e-08, + 2.954642128938358980e-01, 8.871388989825581272e-08, + 3.184537311185345887e-01, 8.669766512784091150e-08, + -3.522205935893520934e-01, 8.477105034722222546e-08, + -3.302416868705768671e-01, 8.292820142663043248e-08, + -3.087354816496132859e-01, 8.116377160904255122e-08, + -2.876820724517809014e-01, 7.947285970052082892e-08, + -2.670627852490452536e-01, 7.785096460459183052e-08, + -2.468600779315257843e-01, 7.629394531250000159e-08, + -2.270574506353460753e-01, 7.479798560049019504e-08, + -2.076393647782444896e-01, 7.335956280048077330e-08, + -1.885911698075500298e-01, 7.197542010613207272e-08, + -1.698990367953974734e-01, 7.064254195601851460e-08, + -1.515498981272009327e-01, 6.935813210227272390e-08, + -1.335313926245226268e-01, 6.811959402901785336e-08, + -1.158318155251217008e-01, 6.692451343201754014e-08, + -9.844007281325252434e-02, 6.577064251077586116e-08, + -8.134563945395240081e-02, 6.465588585805084723e-08, + -6.453852113757117814e-02, 6.357828776041666578e-08, + -4.800921918636060631e-02, 6.253602074795082293e-08, + -3.174869831458029812e-02, 6.152737525201612732e-08, + -1.574835696813916761e-02, 6.055075024801586965e-08, + 0.000000000000000000e+00, 5.960464477539062500e-08, +}; + +static const double C[] = { + 6.931471805599452862e-01, + -2.49887584306188944706e-01, + 3.33368809981254554946e-01, + -5.00000008402474976565e-01 +}; + +#define ln2 C[0] +#define K3 C[1] +#define K2 C[2] +#define K1 C[3] + +float +logf(float x) +{ + double v, t; + float f; + int hx, ix, i, exp, iy; + + hx = *(int *)&x; + ix = hx & ~0x80000000; + + if (ix >= 0x7f800000) /* nan or inf */ + return ((hx < 0)? x * 0.0f : x * x); + + exp = 0; + if (hx < 0x00800000) { /* negative, zero, or subnormal */ + if (hx <= 0) { + f = 0.0f; + return ((ix == 0)? -1.0f / f : f / f); + } + + /* subnormal; scale by 2^149 */ + f = (float)ix; + ix = *(int *)&f; + exp = -149; + } + + exp += (ix - 0x3f320000) >> 23; + ix &= 0x007fffff; + iy = (ix + 0x20000) & 0xfffc0000; + i = iy >> 17; + t = ln2 * (double)exp + TBL[i]; + v = (double)(ix - iy) * TBL[i + 1]; + v += (v * v) * (K1 + v * (K2 + v * K3)); + f = (float)(t + v); + return (f); +} diff --git a/usr/src/lib/libm/common/R/nextafterf.c b/usr/src/lib/libm/common/R/nextafterf.c new file mode 100644 index 0000000000..39db44b552 --- /dev/null +++ b/usr/src/lib/libm/common/R/nextafterf.c @@ -0,0 +1,81 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#if defined(ELFOBJ) +#pragma weak nextafterf = __nextafterf +#endif + +#include "libm.h" + +float +nextafterf(float x, float y) { + float w; + int *pw = (int *) &w; + int *px = (int *) &x; + int *py = (int *) &y; + int ix, iy, iz; + + ix = px[0]; + iy = py[0]; + if ((ix & ~0x80000000) > 0x7f800000) + return (x * y); /* + -> * for Cheetah */ + if ((iy & ~0x80000000) > 0x7f800000) + return (y * x); /* + -> * for Cheetah */ + if (ix == iy || (ix | iy) == 0x80000000) + return (y); /* C99 requirement */ + if ((ix & ~0x80000000) == 0) + iz = 1 | (iy & 0x80000000); + else if (ix > 0) { + if (ix > iy) + iz = ix - 1; + else + iz = ix + 1; + } else { + if (iy < 0 && ix < iy) + iz = ix + 1; + else + iz = ix - 1; + } + pw[0] = iz; + ix = iz & 0x7f800000; + if (ix == 0x7f800000) { + /* raise overflow */ + volatile float t; + + *(int *) &t = 0x7f7fffff; + t *= t; + } else if (ix == 0) { + /* raise underflow */ + volatile float t; + + *(int *) &t = 0x00800000; + t *= t; + } + return (w); +} diff --git a/usr/src/lib/libm/common/R/powf.c b/usr/src/lib/libm/common/R/powf.c new file mode 100644 index 0000000000..8623f9a8fb --- /dev/null +++ b/usr/src/lib/libm/common/R/powf.c @@ -0,0 +1,288 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak powf = __powf + +#include "libm.h" +#include "xpg6.h" /* __xpg6 */ +#define _C99SUSv3_pow _C99SUSv3_pow_treats_Inf_as_an_even_int + +#if defined(__i386) && !defined(__amd64) +extern int __swapRP(int); +#endif + +/* INDENT OFF */ +static const double + ln2 = 6.93147180559945286227e-01, /* 0x3fe62e42, 0xfefa39ef */ + invln2 = 1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */ + dtwo = 2.0, + done = 1.0, + dhalf = 0.5, + d32 = 32.0, + d1_32 = 0.03125, + A0 = 1.999999999813723303647511146995966439250e+0000, + A1 = 6.666910817935858533770138657139665608610e-0001, + t0 = 2.000000000004777489262405315073203746943e+0000, + t1 = 1.666663408349926379873111932994250726307e-0001; + +static const double S[] = { + 1.00000000000000000000e+00, /* 3FF0000000000000 */ + 1.02189714865411662714e+00, /* 3FF059B0D3158574 */ + 1.04427378242741375480e+00, /* 3FF0B5586CF9890F */ + 1.06714040067682369717e+00, /* 3FF11301D0125B51 */ + 1.09050773266525768967e+00, /* 3FF172B83C7D517B */ + 1.11438674259589243221e+00, /* 3FF1D4873168B9AA */ + 1.13878863475669156458e+00, /* 3FF2387A6E756238 */ + 1.16372485877757747552e+00, /* 3FF29E9DF51FDEE1 */ + 1.18920711500272102690e+00, /* 3FF306FE0A31B715 */ + 1.21524735998046895524e+00, /* 3FF371A7373AA9CB */ + 1.24185781207348400201e+00, /* 3FF3DEA64C123422 */ + 1.26905095719173321989e+00, /* 3FF44E086061892D */ + 1.29683955465100964055e+00, /* 3FF4BFDAD5362A27 */ + 1.32523664315974132322e+00, /* 3FF5342B569D4F82 */ + 1.35425554693689265129e+00, /* 3FF5AB07DD485429 */ + 1.38390988196383202258e+00, /* 3FF6247EB03A5585 */ + 1.41421356237309514547e+00, /* 3FF6A09E667F3BCD */ + 1.44518080697704665027e+00, /* 3FF71F75E8EC5F74 */ + 1.47682614593949934623e+00, /* 3FF7A11473EB0187 */ + 1.50916442759342284141e+00, /* 3FF82589994CCE13 */ + 1.54221082540794074411e+00, /* 3FF8ACE5422AA0DB */ + 1.57598084510788649659e+00, /* 3FF93737B0CDC5E5 */ + 1.61049033194925428347e+00, /* 3FF9C49182A3F090 */ + 1.64575547815396494578e+00, /* 3FFA5503B23E255D */ + 1.68179283050742900407e+00, /* 3FFAE89F995AD3AD */ + 1.71861929812247793414e+00, /* 3FFB7F76F2FB5E47 */ + 1.75625216037329945351e+00, /* 3FFC199BDD85529C */ + 1.79470907500310716820e+00, /* 3FFCB720DCEF9069 */ + 1.83400808640934243066e+00, /* 3FFD5818DCFBA487 */ + 1.87416763411029996256e+00, /* 3FFDFC97337B9B5F */ + 1.91520656139714740007e+00, /* 3FFEA4AFA2A490DA */ + 1.95714412417540017941e+00, /* 3FFF50765B6E4540 */ +}; + +static const double TBL[] = { + 0.00000000000000000e+00, + 3.07716586667536873e-02, + 6.06246218164348399e-02, + 8.96121586896871380e-02, + 1.17783035656383456e-01, + 1.45182009844497889e-01, + 1.71850256926659228e-01, + 1.97825743329919868e-01, + 2.23143551314209765e-01, + 2.47836163904581269e-01, + 2.71933715483641758e-01, + 2.95464212893835898e-01, + 3.18453731118534589e-01, + 3.40926586970593193e-01, + 3.62905493689368475e-01, + 3.84411698910332056e-01, + 4.05465108108164385e-01, + 4.26084395310900088e-01, + 4.46287102628419530e-01, + 4.66089729924599239e-01, + 4.85507815781700824e-01, + 5.04556010752395312e-01, + 5.23248143764547868e-01, + 5.41597282432744409e-01, + 5.59615787935422659e-01, + 5.77315365034823613e-01, + 5.94707107746692776e-01, + 6.11801541105992941e-01, + 6.28608659422374094e-01, + 6.45137961373584701e-01, + 6.61398482245365016e-01, + 6.77398823591806143e-01, +}; + +static const float zero = 0.0F, one = 1.0F, huge = 1.0e25f, tiny = 1.0e-25f; +/* INDENT ON */ + +float +powf(float x, float y) { + float fx = x, fy = y; + float fz; + int ix, iy, jx, jy, k, iw, yisint; + + ix = *(int *)&x; + iy = *(int *)&y; + jx = ix & ~0x80000000; + jy = iy & ~0x80000000; + + if (jy == 0) + return (one); /* x**+-0 = 1 */ + else if (ix == 0x3f800000 && (__xpg6 & _C99SUSv3_pow) != 0) + return (one); /* C99: 1**anything = 1 */ + else if (((0x7f800000 - jx) | (0x7f800000 - jy)) < 0) + return (fx * fy); /* at least one of x or y is NaN */ + /* includes Sun: 1**NaN = NaN */ + /* INDENT OFF */ + /* + * determine if y is an odd int + * yisint = 0 ... y is not an integer + * yisint = 1 ... y is an odd int + * yisint = 2 ... y is an even int + */ + /* INDENT ON */ + yisint = 0; + if (ix < 0) { + if (jy >= 0x4b800000) { + yisint = 2; /* |y|>=2**24: y must be even */ + } else if (jy >= 0x3f800000) { + k = (jy >> 23) - 0x7f; /* exponent */ + iw = jy >> (23 - k); + if ((iw << (23 - k)) == jy) + yisint = 2 - (iw & 1); + } + } + + /* special value of y */ + if ((jy & ~0x7f800000) == 0) { + if (jy == 0x7f800000) { /* y is +-inf */ + if (jx == 0x3f800000) { + if ((__xpg6 & _C99SUSv3_pow) != 0) + fz = one; + /* C99: (-1)**+-inf is 1 */ + else + fz = fy - fy; + /* Sun: (+-1)**+-inf = NaN */ + } else if (jx > 0x3f800000) { + /* (|x|>1)**+,-inf = inf,0 */ + if (iy > 0) + fz = fy; + else + fz = zero; + } else { /* (|x|<1)**-,+inf = inf,0 */ + if (iy < 0) + fz = -fy; + else + fz = zero; + } + return (fz); + } else if (jy == 0x3f800000) { /* y is +-1 */ + if (iy < 0) + fx = one / fx; /* y is -1 */ + return (fx); + } else if (iy == 0x40000000) { /* y is 2 */ + return (fx * fx); + } else if (iy == 0x3f000000) { /* y is 0.5 */ + if (jx != 0 && jx != 0x7f800000) + return (sqrtf(x)); + } + } + + /* special value of x */ + if ((jx & ~0x7f800000) == 0) { + if (jx == 0x7f800000 || jx == 0 || jx == 0x3f800000) { + /* x is +-0,+-inf,-1; set fz = |x|**y */ + *(int *)&fz = jx; + if (iy < 0) + fz = one / fz; + if (ix < 0) { + if (jx == 0x3f800000 && yisint == 0) { + /* (-1)**non-int is NaN */ + fz = zero; + fz /= fz; + } else if (yisint == 1) { + /* (x<0)**odd = -(|x|**odd) */ + fz = -fz; + } + } + return (fz); + } + } + + /* (x<0)**(non-int) is NaN */ + if (ix < 0 && yisint == 0) { + fz = zero; + return (fz / fz); + } + + /* + * compute exp(y*log(|x|)) + * fx = *(float *) &jx; + * fz = (float) exp(((double) fy) * log((double) fx)); + */ + { + double dx, dy, dz, ds; + int *px = (int *)&dx, *pz = (int *)&dz, i, n, m; +#if defined(__i386) && !defined(__amd64) + int rp = __swapRP(fp_extended); +#endif + + fx = *(float *)&jx; + dx = (double)fx; + + /* compute log(x)/ln2 */ + i = px[HIWORD] + 0x4000; + n = (i >> 20) - 0x3ff; + pz[HIWORD] = i & 0xffff8000; + pz[LOWORD] = 0; + ds = (dx - dz) / (dx + dz); + i = (i >> 15) & 0x1f; + dz = ds * ds; + dy = invln2 * (TBL[i] + ds * (A0 + dz * A1)); + if (n == 0) + dz = (double)fy * dy; + else + dz = (double)fy * (dy + (double)n); + + /* compute exp2(dz=y*ln(x)) */ + i = pz[HIWORD]; + if ((i & ~0x80000000) >= 0x40640000) { /* |z| >= 160.0 */ + fz = (i > 0)? huge : tiny; + if (ix < 0 && yisint == 1) + fz *= -fz; /* (-ve)**(odd int) */ + else + fz *= fz; +#if defined(__i386) && !defined(__amd64) + if (rp != fp_extended) + (void) __swapRP(rp); +#endif + return (fz); + } + + n = (int)(d32 * dz + (i > 0 ? dhalf : -dhalf)); + i = n & 0x1f; + m = n >> 5; + dy = ln2 * (dz - d1_32 * (double)n); + dx = S[i] * (done - (dtwo * dy) / (dy * (done - dy * t1) - t0)); + if (m != 0) + px[HIWORD] += m << 20; + fz = (float)dx; +#if defined(__i386) && !defined(__amd64) + if (rp != fp_extended) + (void) __swapRP(rp); +#endif + } + + /* end of computing exp(y*log(x)) */ + if (ix < 0 && yisint == 1) + fz = -fz; /* (-ve)**(odd int) */ + return (fz); +} diff --git a/usr/src/lib/libm/common/R/remainderf.c b/usr/src/lib/libm/common/R/remainderf.c new file mode 100644 index 0000000000..e701902608 --- /dev/null +++ b/usr/src/lib/libm/common/R/remainderf.c @@ -0,0 +1,47 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#if defined(ELFOBJ) +#pragma weak remainderf = __remainderf +#endif + +#include "libm.h" + +float +remainderf(float x, float y) { + if (isnanf(x) || isnanf(y)) + return (x * y); + if (y == 0.0f || (*(int *) &x & ~0x80000000) == 0x7f800000) { + /* y is 0 or x is infinite; raise invalid and return NaN */ + y = 0.0f; + *(int *) &x = 0x7f800000; + return (x * y); + } + return ((float) remainder((double) x, (double) y)); +} diff --git a/usr/src/lib/libm/common/R/rintf.c b/usr/src/lib/libm/common/R/rintf.c new file mode 100644 index 0000000000..c958dfd942 --- /dev/null +++ b/usr/src/lib/libm/common/R/rintf.c @@ -0,0 +1,166 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#if defined(ELFOBJ) +#pragma weak aintf = __aintf +#pragma weak anintf = __anintf +#pragma weak irintf = __irintf +#pragma weak nintf = __nintf +#pragma weak rintf = __rintf +#endif + +/* INDENT OFF */ +/* + * aintf(x) return x chopped to integral value + * anintf(x) return sign(x)*(|x|+0.5) chopped to integral value + * irintf(x) return rint(x) in integer format + * nintf(x) return anint(x) in integer format + * rintf(x) return x rounded to integral according to the rounding direction + * + * NOTE: rintf(x), aintf(x) and anintf(x) return results with the same sign as + * x's, including 0.0. + */ + +#include "libm.h" + +static const float xf[] = { +/* ZEROF */ 0.0f, +/* TWO_23F */ 8.3886080000e6f, +/* MTWO_23F */ -8.3886080000e6f, +/* ONEF */ 1.0f, +/* MONEF */ -1.0f, +/* HALFF */ 0.5f, +/* MHALFF */ -0.5f, +/* HUGEF */ 1.0e30f, +}; + +#define ZEROF xf[0] +#define TWO_23F xf[1] +#define MTWO_23F xf[2] +#define ONEF xf[3] +#define MONEF xf[4] +#define HALFF xf[5] +#define MHALFF xf[6] +#define HUGEF xf[7] +/* INDENT ON */ + +float +aintf(float x) { + int hx, k; + float y; + + hx = *(int *) &x; + k = (hx & ~0x80000000) >> 23; + if (k < 150) { + y = (float) ((int) x); + /* + * make sure y has the same sign of x when |x|<0.5 + * (i.e., y=0.0) + */ + return (((k - 127) & hx) < 0 ? -y : y); + } else + /* signal invalid if x is a SNaN */ + return (x * ONEF); /* +0 -> *1 for Cheetah */ +} + +float +anintf(float x) { + volatile float dummy; + int hx, k, j, ix; + + hx = *(int *) &x; + ix = hx & ~0x80000000; + k = ix >> 23; + if (((k - 127) ^ (k - 150)) < 0) { + j = 1 << (149 - k); + k = j + j - 1; + if ((k & hx) != 0) + dummy = HUGEF + x; /* raise inexact */ + *(int *) &x = (hx + j) & ~k; + return (x); + } else if (k <= 126) { + dummy = HUGEF + x; + *(int *) &x = (0x3f800000 & ((125 - k) >> 31)) | + (0x80000000 & hx); + return (x); + } else + /* signal invalid if x is a SNaN */ + return (x * ONEF); /* +0 -> *1 for Cheetah */ +} + +int +irintf(float x) { + float v; + int hx, k; + + hx = *(int *) &x; + k = (hx & ~0x80000000) >> 23; + v = xf[((k - 150) >> 31) & (1 - (hx >> 31))]; + return ((int) ((float) (x + v) - v)); +} + +int +nintf(float x) { + int hx, ix, k, j, m; + volatile float dummy; + + hx = *(int *) &x; + k = (hx & ~0x80000000) >> 23; + if (((k - 126) ^ (k - 150)) < 0) { + ix = (hx & 0x00ffffff) | 0x800000; + m = 149 - k; + j = 1 << m; + if ((ix & (j + j - 1)) != 0) + dummy = HUGEF + x; + hx = hx >> 31; + return ((((ix + j) >> (m + 1)) ^ hx) - hx); + } else + return ((int) x); +} + +float +rintf(float x) { + float w, v; + int hx, k; + + hx = *(int *) &x; + k = (hx & ~0x80000000) >> 23; +#if defined(FPADD_TRAPS_INCOMPLETE_ON_NAN) + if (k >= 150) + return (x * ONEF); + v = xf[1 - (hx >> 31)]; +#else + v = xf[((k - 150) >> 31) & (1 - (hx >> 31))]; +#endif + w = (float) (x + v); + if (k < 127 && w == v) + return (ZEROF * x); + else + return (w - v); +} diff --git a/usr/src/lib/libm/common/R/scalbf.c b/usr/src/lib/libm/common/R/scalbf.c new file mode 100644 index 0000000000..589eac0931 --- /dev/null +++ b/usr/src/lib/libm/common/R/scalbf.c @@ -0,0 +1,60 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak scalbf = __scalbf + +#include "libm.h" + +float +scalbf(float x, float y) { + int ix, iy, hx, hy, n; + + ix = *(int *)&x; + iy = *(int *)&y; + hx = ix & ~0x80000000; + hy = iy & ~0x80000000; + + if (hx > 0x7f800000 || hy >= 0x7f800000) { + /* x is nan or y is inf or nan */ + return ((iy < 0)? x / -y : x * y); + } + + /* see if y is an integer without raising inexact */ + if (hy >= 0x4b000000) { + /* |y| >= 2^23, so it must be an integer */ + n = (iy < 0)? -65000 : 65000; + } else if (hy < 0x3f800000) { + /* |y| < 1, so it must be zero or non-integer */ + return ((hy == 0)? x : (x - x) / (x - x)); + } else { + if (hy & ((1 << (0x96 - (hy >> 23))) - 1)) + return ((y - y) / (y - y)); + n = (int)y; + } + return (scalbnf(x, n)); +} diff --git a/usr/src/lib/libm/common/R/scalbnf.c b/usr/src/lib/libm/common/R/scalbnf.c new file mode 100644 index 0000000000..fab79011fc --- /dev/null +++ b/usr/src/lib/libm/common/R/scalbnf.c @@ -0,0 +1,97 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#if defined(ELFOBJ) +#pragma weak scalbnf = __scalbnf +#endif + +#include "libm.h" +#include <float.h> /* FLT_MAX, FLT_MIN */ +#include <stdlib.h> /* abs */ + +static const float twom25f = 2.98023223876953125e-8F; +#if defined(USE_FPSCALE) || defined(__x86) +static const float two23f = 8388608.0F; +#else +/* + * v: a non-zero subnormal |x|; returns [-22, 0] + */ +static int +ilogbf_biased(unsigned v) { + int r = -22; + + if (v & 0xffff0000) + r += 16, v >>= 16; + if (v & 0xff00) + r += 8, v >>= 8; + if (v & 0xf0) + r += 4, v >>= 4; + v <<= 1; + return (r + ((0xffffaa50 >> v) & 0x3)); +} +#endif /* defined(USE_FPSCALE) */ + +float +scalbnf(float x, int n) { + int *px = (int *) &x, ix, k; + + ix = *px & ~0x80000000; + k = ix >> 23; + if (k == 0xff) +#if defined(FPADD_TRAPS_INCOMPLETE_ON_NAN) + return (ix > 0x7f800000 ? x * x : x); +#else + return (x + x); +#endif + if (ix == 0 || n == 0) + return (x); + if (k == 0) { +#if defined(USE_FPSCALE) || defined(__x86) + x *= two23f; + k = ((*px & ~0x80000000) >> 23) - 23; +#else + k = ilogbf_biased(ix); + *px = (*px & 0x80000000) | (ix << (-k + 1)); +#endif + } + if ((unsigned) abs(n) >= 131072) /* cast to unsigned for -2^31 */ + n >>= 1; /* avoid subsequent integer overflow */ + k += n; + if (k > 0xfe) + return (FLT_MAX * copysignf(FLT_MAX, x)); + if (k <= -25) + return (FLT_MIN * copysignf(FLT_MIN, x)); + if (k > 0) { + *px = (*px & ~0x7f800000) | (k << 23); + return (x); + } + k += 25; + *px = (*px & ~0x7f800000) | (k << 23); + return (x * twom25f); +} diff --git a/usr/src/lib/libm/common/R/signgamf.c b/usr/src/lib/libm/common/R/signgamf.c new file mode 100644 index 0000000000..3b9c3fc063 --- /dev/null +++ b/usr/src/lib/libm/common/R/signgamf.c @@ -0,0 +1,34 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak signgamf = __signgamf + +#include "libm.h" + +int signgamf = 0; diff --git a/usr/src/lib/libm/common/R/significandf.c b/usr/src/lib/libm/common/R/significandf.c new file mode 100644 index 0000000000..1e9c81f7ec --- /dev/null +++ b/usr/src/lib/libm/common/R/significandf.c @@ -0,0 +1,48 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#if defined(ELFOBJ) +#pragma weak significandf = __significandf +#endif + +#include "libm.h" + +float +significandf(float x) { + int ix = *(int *) &x & ~0x80000000; + + if (ix == 0 || ix >= 0x7f800000) /* 0/+-Inf/NaN */ +#if defined(FPADD_TRAPS_INCOMPLETE_ON_NAN) + return (ix > 0x7f800000 ? x * x : x); +#else + return (x + x); +#endif + else + return (scalbnf(x, -ilogbf(x))); +} diff --git a/usr/src/lib/libm/common/R/sincosf.c b/usr/src/lib/libm/common/R/sincosf.c new file mode 100644 index 0000000000..73b8c731d4 --- /dev/null +++ b/usr/src/lib/libm/common/R/sincosf.c @@ -0,0 +1,187 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak sincosf = __sincosf + +/* INDENT OFF */ +/* + * For |x| < pi/4, let z = x * x, and approximate sin(x) by + * + * S(x) = x(S0 + S1*z)(S2 + S3*z + z*z) + * where + * S0 = 1.85735322054308378716204874632872525989806770558e-0003, + * S1 = -1.95035094218403635082921458859320791358115801259e-0004, + * S2 = 5.38400550766074785970952495168558701485841707252e+0002, + * S3 = -3.31975110777873728964197739157371509422022905947e+0001, + * + * with error bounded by |(sin(x) - S(x))/x| < 2**(-28.2), and + * cos(x) by + * + * C(x) = (C0 + C1*z + C2*z*z) * (C3 + C4*z + z*z) + * where + * C0 = 1.09349482127188401868272000389539985058873853699e-0003 + * C1 = -5.03324285989964979398034700054920226866107675091e-0004 + * C2 = 2.43792880266971107750418061559602239831538067410e-0005 + * C3 = 9.14499072605666582228127405245558035523741471271e+0002 + * C4 = -3.63151270591815439197122504991683846785293207730e+0001 + * + * with error bounded by |cos(x) - C(x)| < 2**(-34.2). + */ +/* INDENT ON */ + +#include "libm.h" + +extern const int _TBL_ipio2_inf[]; +extern int __rem_pio2m(double *, double *, int, int, int, const int *); +#if defined(__i386) && !defined(__amd64) +extern int __swapRP(int); +#endif + +static const double C[] = { + 1.85735322054308378716204874632872525989806770558e-0003, + -1.95035094218403635082921458859320791358115801259e-0004, + 5.38400550766074785970952495168558701485841707252e+0002, + -3.31975110777873728964197739157371509422022905947e+0001, + 1.09349482127188401868272000389539985058873853699e-0003, + -5.03324285989964979398034700054920226866107675091e-0004, + 2.43792880266971107750418061559602239831538067410e-0005, + 9.14499072605666582228127405245558035523741471271e+0002, + -3.63151270591815439197122504991683846785293207730e+0001, + 0.636619772367581343075535, /* 2^ -1 * 1.45F306DC9C883 */ + 0.5, + 1.570796326734125614166, /* 2^ 0 * 1.921FB54400000 */ + 6.077100506506192601475e-11, /* 2^-34 * 1.0B4611A626331 */ +}; + +#define S0 C[0] +#define S1 C[1] +#define S2 C[2] +#define S3 C[3] +#define C0 C[4] +#define C1 C[5] +#define C2 C[6] +#define C3 C[7] +#define C4 C[8] +#define invpio2 C[9] +#define half C[10] +#define pio2_1 C[11] +#define pio2_t C[12] + +void +sincosf(float x, float *s, float *c) +{ + double y, z, w; + float f, g; + int n, ix, hx, hy; + volatile int i; + + hx = *((int *)&x); + ix = hx & 0x7fffffff; + + y = (double)x; + + if (ix <= 0x4016cbe4) { /* |x| < 3*pi/4 */ + if (ix <= 0x3f490fdb) { /* |x| < pi/4 */ + if (ix <= 0x39800000) { /* |x| <= 2**-12 */ + i = (int)y; +#ifdef lint + i = i; +#endif + *s = x; + *c = 1.0f; + return; + } + z = y * y; + *s = (float)((y * (S0 + z * S1)) * + (S2 + z * (S3 + z))); + *c = (float)(((C0 + z * C1) + (z * z) * C2) * + (C3 + z * (C4 + z))); + } else if (hx > 0) { + y = (y - pio2_1) - pio2_t; + z = y * y; + *s = (float)(((C0 + z * C1) + (z * z) * C2) * + (C3 + z * (C4 + z))); + *c = (float)-((y * (S0 + z * S1)) * + (S2 + z * (S3 + z))); + } else { + y = (y + pio2_1) + pio2_t; + z = y * y; + *s = (float)-(((C0 + z * C1) + (z * z) * C2) * + (C3 + z * (C4 + z))); + *c = (float)((y * (S0 + z * S1)) * + (S2 + z * (S3 + z))); + } + return; + } else if (ix <= 0x49c90fdb) { /* |x| < 2^19*pi */ +#if defined(__i386) && !defined(__amd64) + int rp; + + rp = __swapRP(fp_extended); +#endif + w = y * invpio2; + if (hx < 0) + n = (int)(w - half); + else + n = (int)(w + half); + y = (y - n * pio2_1) - n * pio2_t; +#if defined(__i386) && !defined(__amd64) + if (rp != fp_extended) + (void) __swapRP(rp); +#endif + } else { + if (ix >= 0x7f800000) { + *s = *c = x / x; + return; + } + hy = ((int *)&y)[HIWORD]; + n = ((hy >> 20) & 0x7ff) - 1046; + ((int *)&w)[HIWORD] = (hy & 0xfffff) | 0x41600000; + ((int *)&w)[LOWORD] = ((int *)&y)[LOWORD]; + n = __rem_pio2m(&w, &y, n, 1, 0, _TBL_ipio2_inf); + if (hy < 0) { + y = -y; + n = -n; + } + } + + z = y * y; + f = (float)((y * (S0 + z * S1)) * (S2 + z * (S3 + z))); + g = (float)(((C0 + z * C1) + (z * z) * C2) * + (C3 + z * (C4 + z))); + if (n & 2) { + f = -f; + g = -g; + } + if (n & 1) { + *s = g; + *c = -f; + } else { + *s = f; + *c = g; + } +} diff --git a/usr/src/lib/libm/common/R/sincospif.c b/usr/src/lib/libm/common/R/sincospif.c new file mode 100644 index 0000000000..414feb52e1 --- /dev/null +++ b/usr/src/lib/libm/common/R/sincospif.c @@ -0,0 +1,51 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak sincospif = __sincospif + +#include "libm.h" + +extern void sincospi(double, double *, double *); + +void +sincospif(float x, float *s, float *c) { + double ds, dc; + +#if defined(FPADD_TRAPS_INCOMPLETE_ON_NAN) + if (isnanf(x)) + *s = *c = x * x; + else { +#endif + sincospi((double) x, &ds, &dc); + *s = (float) ds; + *c = (float) dc; +#if defined(FPADD_TRAPS_INCOMPLETE_ON_NAN) + } +#endif +} diff --git a/usr/src/lib/libm/common/R/sinf.c b/usr/src/lib/libm/common/R/sinf.c new file mode 100644 index 0000000000..fe194621ab --- /dev/null +++ b/usr/src/lib/libm/common/R/sinf.c @@ -0,0 +1,151 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak sinf = __sinf + +/* + * See sincosf.c + */ + +#include "libm.h" + +extern const int _TBL_ipio2_inf[]; +extern int __rem_pio2m(double *, double *, int, int, int, const int *); +#if defined(__i386) && !defined(__amd64) +extern int __swapRP(int); +#endif + +static const double C[] = { + 1.85735322054308378716204874632872525989806770558e-0003, + -1.95035094218403635082921458859320791358115801259e-0004, + 5.38400550766074785970952495168558701485841707252e+0002, + -3.31975110777873728964197739157371509422022905947e+0001, + 1.09349482127188401868272000389539985058873853699e-0003, + -5.03324285989964979398034700054920226866107675091e-0004, + 2.43792880266971107750418061559602239831538067410e-0005, + 9.14499072605666582228127405245558035523741471271e+0002, + -3.63151270591815439197122504991683846785293207730e+0001, + 0.636619772367581343075535, /* 2^ -1 * 1.45F306DC9C883 */ + 0.5, + 1.570796326734125614166, /* 2^ 0 * 1.921FB54400000 */ + 6.077100506506192601475e-11, /* 2^-34 * 1.0B4611A626331 */ +}; + +#define S0 C[0] +#define S1 C[1] +#define S2 C[2] +#define S3 C[3] +#define C0 C[4] +#define C1 C[5] +#define C2 C[6] +#define C3 C[7] +#define C4 C[8] +#define invpio2 C[9] +#define half C[10] +#define pio2_1 C[11] +#define pio2_t C[12] + +float +sinf(float x) +{ + double y, z, w; + float f; + int n, ix, hx, hy; + volatile int i; + + hx = *((int *)&x); + ix = hx & 0x7fffffff; + + y = (double)x; + + if (ix <= 0x4016cbe4) { /* |x| < 3*pi/4 */ + if (ix <= 0x3f490fdb) { /* |x| < pi/4 */ + if (ix <= 0x39800000) { /* |x| <= 2**-12 */ + i = (int)y; +#ifdef lint + i = i; +#endif + return (x); + } + z = y * y; + return ((float)((y * (S0 + z * S1)) * + (S2 + z * (S3 + z)))); + } else if (hx > 0) { + y = (y - pio2_1) - pio2_t; + z = y * y; + return ((float)(((C0 + z * C1) + (z * z) * C2) * + (C3 + z * (C4 + z)))); + } else { + y = (y + pio2_1) + pio2_t; + z = y * y; + return ((float)-(((C0 + z * C1) + (z * z) * C2) * + (C3 + z * (C4 + z)))); + } + } else if (ix <= 0x49c90fdb) { /* |x| < 2^19*pi */ +#if defined(__i386) && !defined(__amd64) + int rp; + + rp = __swapRP(fp_extended); +#endif + w = y * invpio2; + if (hx < 0) + n = (int)(w - half); + else + n = (int)(w + half); + y = (y - n * pio2_1) - n * pio2_t; +#if defined(__i386) && !defined(__amd64) + if (rp != fp_extended) + (void) __swapRP(rp); +#endif + } else { + if (ix >= 0x7f800000) + return (x / x); /* sin(Inf or NaN) is NaN */ + hy = ((int *)&y)[HIWORD]; + n = ((hy >> 20) & 0x7ff) - 1046; + ((int *)&w)[HIWORD] = (hy & 0xfffff) | 0x41600000; + ((int *)&w)[LOWORD] = ((int *)&y)[LOWORD]; + n = __rem_pio2m(&w, &y, n, 1, 0, _TBL_ipio2_inf); + if (hy < 0) { + y = -y; + n = -n; + } + } + + if (n & 1) { + /* compute cos y */ + z = y * y; + f = (float)(((C0 + z * C1) + (z * z) * C2) * + (C3 + z * (C4 + z))); + } else { + /* compute sin y */ + z = y * y; + f = (float)((y * (S0 + z * S1)) * (S2 + z * (S3 + z))); + } + + return ((n & 2)? -f : f); +} diff --git a/usr/src/lib/libm/common/R/sinhf.c b/usr/src/lib/libm/common/R/sinhf.c new file mode 100644 index 0000000000..2e807aaacd --- /dev/null +++ b/usr/src/lib/libm/common/R/sinhf.c @@ -0,0 +1,51 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak sinhf = __sinhf + +#include "libm.h" + +float +sinhf(float x) { + double s; + float w; + int hx, ix; + + hx = *(int *)&x; + ix = hx & ~0x80000000; + if (ix >= 0x7f800000) { + /* sinhf(x) is x if x is +-Inf or NaN */ + return (x * 1.0f); + } + if (ix >= 0x43000000) /* sinhf(x) trivially overflows */ + s = (hx < 0)? -1.0e100 : 1.0e100; + else + s = sinh((double)x); + w = (float)s; + return (w); +} diff --git a/usr/src/lib/libm/common/R/sqrtf.c b/usr/src/lib/libm/common/R/sqrtf.c new file mode 100644 index 0000000000..125fd4b03d --- /dev/null +++ b/usr/src/lib/libm/common/R/sqrtf.c @@ -0,0 +1,109 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak sqrtf = __sqrtf + +#include "libm.h" + +#ifdef __INLINE + +extern float __inline_sqrtf(float); + +float +sqrtf(float x) { + return (__inline_sqrtf(x)); +} + +#else /* defined(__INLINE) */ + +static const float huge = 1.0e35F, tiny = 1.0e-35F, zero = 0.0f; + +float +sqrtf(float x) { + float dz, w; + int *pw = (int *)&w; + int ix, j, r, q, m, n, s, t; + + w = x; + ix = pw[0]; + if (ix <= 0) { + /* x is <= 0 or nan */ + j = ix & 0x7fffffff; + if (j == 0) + return (w); + return ((w * zero) / zero); + } + + if ((ix & 0x7f800000) == 0x7f800000) { + /* x is +inf or nan */ + return (w * w); + } + + m = ir_ilogb_(&w); + n = -m; + w = r_scalbn_(&w, (int *)&n); + ix = (pw[0] & 0x007fffff) | 0x00800000; + n = m / 2; + if ((n + n) != m) { + ix = ix + ix; + m -= 1; + n = m / 2; + } + + /* generate sqrt(x) bit by bit */ + ix <<= 1; + q = s = 0; + r = 0x01000000; + for (j = 1; j <= 25; j++) { + t = s + r; + if (t <= ix) { + s = t + r; + ix -= t; + q += r; + } + ix <<= 1; + r >>= 1; + } + if (ix == 0) + goto done; + + /* raise inexact and determine the ambient rounding mode */ + dz = huge - tiny; + if (dz < huge) + goto done; + dz = huge + tiny; + if (dz > huge) + q += 1; + q += (q & 1); + +done: + pw[0] = (q >> 1) + 0x3f000000; + return (r_scalbn_(&w, (int *)&n)); +} + +#endif /* defined(__INLINE) */ diff --git a/usr/src/lib/libm/common/R/tanf.c b/usr/src/lib/libm/common/R/tanf.c new file mode 100644 index 0000000000..cc57c66bbb --- /dev/null +++ b/usr/src/lib/libm/common/R/tanf.c @@ -0,0 +1,159 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak tanf = __tanf + +#include "libm.h" + +extern const int _TBL_ipio2_inf[]; +extern int __rem_pio2m(double *, double *, int, int, int, const int *); +#if defined(__i386) && !defined(__amd64) +extern int __swapRP(int); +#endif + +static const double C[] = { + 1.0, + 4.46066928428959230679140546271810308098793029785e-0003, + 4.92165316309189027066395283327437937259674072266e+0000, + -7.11410648161473480044492134766187518835067749023e-0001, + 4.08549808374053391446523164631798863410949707031e+0000, + 2.50411070398050927821032018982805311679840087891e+0000, + 1.11492064560251158411574579076841473579406738281e+0001, + -1.50565540968422650891511693771462887525558471680e+0000, + -1.81484378878349295050043110677506774663925170898e+0000, + 3.333335997532835641297409611782510896641e-0001, + 2.999997598248363761541668282006867229939e+00, + 0.636619772367581343075535, /* 2^ -1 * 1.45F306DC9C883 */ + 0.5, + 1.570796326734125614166, /* 2^ 0 * 1.921FB54400000 */ + 6.077100506506192601475e-11, /* 2^-34 * 1.0B4611A626331 */ +}; + +#define one C[0] +#define P0 C[1] +#define P1 C[2] +#define P2 C[3] +#define P3 C[4] +#define P4 C[5] +#define P5 C[6] +#define P6 C[7] +#define P7 C[8] +#define T0 C[9] +#define T1 C[10] +#define invpio2 C[11] +#define half C[12] +#define pio2_1 C[13] +#define pio2_t C[14] + +float +tanf(float x) +{ + double y, z, w; + float f; + int n, ix, hx, hy; + volatile int i; + + hx = *((int *)&x); + ix = hx & 0x7fffffff; + + y = (double)x; + + if (ix <= 0x4016cbe4) { /* |x| < 3*pi/4 */ + if (ix <= 0x3f490fdb) { /* |x| < pi/4 */ + if (ix < 0x3c000000) { /* |x| < 2**-7 */ + if (ix <= 0x39800000) { /* |x| < 2**-12 */ + i = (int)y; +#ifdef lint + i = i; +#endif + return (x); + } + return ((float)((y * T0) * (T1 + y * y))); + } + z = y * y; + return ((float)(((P0 * y) * (P1 + z * (P2 + z)) * + (P3 + z * (P4 + z))) * + (P5 + z * (P6 + z * (P7 + z))))); + } + if (hx > 0) + y = (y - pio2_1) - pio2_t; + else + y = (y + pio2_1) + pio2_t; + hy = ((int *)&y)[HIWORD] & ~0x80000000; + if (hy < 0x3f800000) { /* |y| < 2**-7 */ + z = (y * T0) * (T1 + y * y); + return ((float)(-one / z)); + } + z = y * y; + w = ((P0 * y) * (P1 + z * (P2 + z)) * (P3 + z * (P4 + z))) * + (P5 + z * (P6 + z * (P7 + z))); + return ((float)(-one / w)); + } + + if (ix <= 0x49c90fdb) { /* |x| < 2^19*pi */ +#if defined(__i386) && !defined(__amd64) + int rp; + + rp = __swapRP(fp_extended); +#endif + w = y * invpio2; + if (hx < 0) + n = (int)(w - half); + else + n = (int)(w + half); + y = (y - n * pio2_1) - n * pio2_t; +#if defined(__i386) && !defined(__amd64) + if (rp != fp_extended) + (void) __swapRP(rp); +#endif + } else { + if (ix >= 0x7f800000) + return (x / x); /* sin(Inf or NaN) is NaN */ + hy = ((int *)&y)[HIWORD]; + n = ((hy >> 20) & 0x7ff) - 1046; + ((int *)&w)[HIWORD] = (hy & 0xfffff) | 0x41600000; + ((int *)&w)[LOWORD] = ((int *)&y)[LOWORD]; + n = __rem_pio2m(&w, &y, n, 1, 0, _TBL_ipio2_inf); + if (hy < 0) { + y = -y; + n = -n; + } + } + + hy = ((int *)&y)[HIWORD] & ~0x80000000; + if (hy < 0x3f800000) { /* |y| < 2**-7 */ + z = (y * T0) * (T1 + y * y); + f = ((n & 1) == 0)? (float)z : (float)(-one / z); + return (f); + } + z = y * y; + w = ((P0 * y) * (P1 + z * (P2 + z)) * (P3 + z * (P4 + z))) * + (P5 + z * (P6 + z * (P7 + z))); + f = ((n & 1) == 0)? (float)w : (float)(-one / w); + return (f); +} diff --git a/usr/src/lib/libm/common/R/tanhf.c b/usr/src/lib/libm/common/R/tanhf.c new file mode 100644 index 0000000000..aed4b24613 --- /dev/null +++ b/usr/src/lib/libm/common/R/tanhf.c @@ -0,0 +1,42 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak tanhf = __tanhf + +#include "libm.h" + +float +tanhf(float x) { +#if defined(FPADD_TRAPS_INCOMPLETE_ON_NAN) + if (isnanf(x)) + return (x * x); + else +#endif + return ((float) tanh((double) x)); +} |