125c28e83SPiotr Jasiukajtis /*
225c28e83SPiotr Jasiukajtis  * CDDL HEADER START
325c28e83SPiotr Jasiukajtis  *
425c28e83SPiotr Jasiukajtis  * The contents of this file are subject to the terms of the
525c28e83SPiotr Jasiukajtis  * Common Development and Distribution License (the "License").
625c28e83SPiotr Jasiukajtis  * You may not use this file except in compliance with the License.
725c28e83SPiotr Jasiukajtis  *
825c28e83SPiotr Jasiukajtis  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
925c28e83SPiotr Jasiukajtis  * or http://www.opensolaris.org/os/licensing.
1025c28e83SPiotr Jasiukajtis  * See the License for the specific language governing permissions
1125c28e83SPiotr Jasiukajtis  * and limitations under the License.
1225c28e83SPiotr Jasiukajtis  *
1325c28e83SPiotr Jasiukajtis  * When distributing Covered Code, include this CDDL HEADER in each
1425c28e83SPiotr Jasiukajtis  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1525c28e83SPiotr Jasiukajtis  * If applicable, add the following below this CDDL HEADER, with the
1625c28e83SPiotr Jasiukajtis  * fields enclosed by brackets "[]" replaced with your own identifying
1725c28e83SPiotr Jasiukajtis  * information: Portions Copyright [yyyy] [name of copyright owner]
1825c28e83SPiotr Jasiukajtis  *
1925c28e83SPiotr Jasiukajtis  * CDDL HEADER END
2025c28e83SPiotr Jasiukajtis  */
2125c28e83SPiotr Jasiukajtis 
2225c28e83SPiotr Jasiukajtis /*
2325c28e83SPiotr Jasiukajtis  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
2425c28e83SPiotr Jasiukajtis  * Use is subject to license terms.
2525c28e83SPiotr Jasiukajtis  */
2625c28e83SPiotr Jasiukajtis 
2725c28e83SPiotr Jasiukajtis /*
2825c28e83SPiotr Jasiukajtis  * Copyright 2011, Richard Lowe.
2925c28e83SPiotr Jasiukajtis  */
3025c28e83SPiotr Jasiukajtis 
3125c28e83SPiotr Jasiukajtis /* Functions in this file are duplicated in locallibm.il.  Keep them in sync */
3225c28e83SPiotr Jasiukajtis 
3325c28e83SPiotr Jasiukajtis #ifndef _LIBM_INLINES_H
3425c28e83SPiotr Jasiukajtis #define	_LIBM_INLINES_H
3525c28e83SPiotr Jasiukajtis 
3625c28e83SPiotr Jasiukajtis #ifdef __GNUC__
3725c28e83SPiotr Jasiukajtis 
3825c28e83SPiotr Jasiukajtis #include <sys/types.h>
3925c28e83SPiotr Jasiukajtis #include <sys/ieeefp.h>
4025c28e83SPiotr Jasiukajtis 
4125c28e83SPiotr Jasiukajtis #ifdef __cplusplus
4225c28e83SPiotr Jasiukajtis extern "C" {
4325c28e83SPiotr Jasiukajtis #endif
4425c28e83SPiotr Jasiukajtis 
45*7f11fd00SRichard Lowe extern __GNU_INLINE enum fp_class_type
fp_classf(float f)4625c28e83SPiotr Jasiukajtis fp_classf(float f)
4725c28e83SPiotr Jasiukajtis {
4825c28e83SPiotr Jasiukajtis 	enum fp_class_type ret;
4925c28e83SPiotr Jasiukajtis 	int fint;		/* scratch for f as int */
5025c28e83SPiotr Jasiukajtis 	uint64_t tmp;
5125c28e83SPiotr Jasiukajtis 
5225c28e83SPiotr Jasiukajtis 	__asm__ __volatile__(
5325c28e83SPiotr Jasiukajtis 	    "fabss  %3,%3\n\t"
5425c28e83SPiotr Jasiukajtis 	    "st	    %3,%1\n\t"
5525c28e83SPiotr Jasiukajtis 	    "ld	    %1,%0\n\t"
5625c28e83SPiotr Jasiukajtis 	    "orcc   %%g0,%0,%%g0\n\t"
5725c28e83SPiotr Jasiukajtis 	    "be,pn  %%icc,2f\n\t"
5825c28e83SPiotr Jasiukajtis 	    "nop\n\t"
5925c28e83SPiotr Jasiukajtis 	    "1:\n\t"
6025c28e83SPiotr Jasiukajtis 	    "sethi  %%hi(0x7f800000),%2\n\t"
6125c28e83SPiotr Jasiukajtis 	    "andcc  %0,%2,%%g0\n\t"
6225c28e83SPiotr Jasiukajtis 	    "bne,pt %%icc,1f\n\t"
6325c28e83SPiotr Jasiukajtis 	    "nop\n\t"
6425c28e83SPiotr Jasiukajtis 	    "or	    %%g0,1,%0\n\t"
6525c28e83SPiotr Jasiukajtis 	    "ba	    2f\n\t"	/* subnormal */
6625c28e83SPiotr Jasiukajtis 	    "nop\n\t"
6725c28e83SPiotr Jasiukajtis 	    "1:\n\t"
6825c28e83SPiotr Jasiukajtis 	    "subcc  %0,%2,%%g0\n\t"
6925c28e83SPiotr Jasiukajtis 	    "bge,pn %%icc,1f\n\t"
7025c28e83SPiotr Jasiukajtis 	    "nop\n\t"
7125c28e83SPiotr Jasiukajtis 	    "or	    %%g0,2,%0\n\t"
7225c28e83SPiotr Jasiukajtis 	    "ba	    2f\n\t"	/* normal */
7325c28e83SPiotr Jasiukajtis 	    "nop\n\t"
7425c28e83SPiotr Jasiukajtis 	    "1:\n\t"
7525c28e83SPiotr Jasiukajtis 	    "bg,pn  %%icc,1f\n\t"
7625c28e83SPiotr Jasiukajtis 	    "nop\n\t"
7725c28e83SPiotr Jasiukajtis 	    "or	    %%g0,3,%0\n\t"
7825c28e83SPiotr Jasiukajtis 	    "ba	    2f\n\t"	/* infinity */
7925c28e83SPiotr Jasiukajtis 	    "nop\n\t"
8025c28e83SPiotr Jasiukajtis 	    "1:\n\t"
8125c28e83SPiotr Jasiukajtis 	    "sethi  %%hi(0x00400000),%2\n\t"
8225c28e83SPiotr Jasiukajtis 	    "andcc  %0,%2,%%g0\n\t"
8325c28e83SPiotr Jasiukajtis 	    "or	    %%g0,4,%0\n\t"
8425c28e83SPiotr Jasiukajtis 	    "bne,pt %%icc,2f\n\t" /* quiet NaN */
8525c28e83SPiotr Jasiukajtis 	    "nop\n\t"
8625c28e83SPiotr Jasiukajtis 	    "or	    %%g0,5,%0\n\t" /* signalling NaN */
8725c28e83SPiotr Jasiukajtis 	    "2:\n\t"
8825c28e83SPiotr Jasiukajtis 	    : "=r" (ret), "=m" (fint), "=r" (tmp), "+f" (f)
8925c28e83SPiotr Jasiukajtis 	    :
9025c28e83SPiotr Jasiukajtis 	    : "cc");
9125c28e83SPiotr Jasiukajtis 
9225c28e83SPiotr Jasiukajtis 	return (ret);
9325c28e83SPiotr Jasiukajtis }
9425c28e83SPiotr Jasiukajtis 
95*7f11fd00SRichard Lowe extern __GNU_INLINE enum fp_class_type
fp_class(double d)9625c28e83SPiotr Jasiukajtis fp_class(double d)
9725c28e83SPiotr Jasiukajtis {
9825c28e83SPiotr Jasiukajtis 	enum fp_class_type ret;
9925c28e83SPiotr Jasiukajtis 	uint64_t dint;		/* Scratch for d-as-long */
10025c28e83SPiotr Jasiukajtis 	uint64_t tmp;
10125c28e83SPiotr Jasiukajtis 
10225c28e83SPiotr Jasiukajtis 	__asm__ __volatile__(
10325c28e83SPiotr Jasiukajtis 	    "fabsd  %3,%3\n\t"
10425c28e83SPiotr Jasiukajtis 	    "std    %3,%1\n\t"
10525c28e83SPiotr Jasiukajtis 	    "ldx    %1,%0\n\t"
10625c28e83SPiotr Jasiukajtis 	    "orcc   %%g0,%0,%%g0\n\t"
10725c28e83SPiotr Jasiukajtis 	    "be,pn  %%xcc,2f\n\t"
10825c28e83SPiotr Jasiukajtis 	    "nop\n\t"
10925c28e83SPiotr Jasiukajtis 	    "sethi  %%hi(0x7ff00000),%2\n\t"
11025c28e83SPiotr Jasiukajtis 	    "sllx   %2,32,%2\n\t"
11125c28e83SPiotr Jasiukajtis 	    "andcc  %0,%2,%%g0\n\t"
11225c28e83SPiotr Jasiukajtis 	    "bne,pt %%xcc,1f\n\t"
11325c28e83SPiotr Jasiukajtis 	    "nop\n\t"
11425c28e83SPiotr Jasiukajtis 	    "or	    %%g0,1,%0\n\t"
11525c28e83SPiotr Jasiukajtis 	    "ba	    2f\n\t"
11625c28e83SPiotr Jasiukajtis 	    "nop\n\t"
11725c28e83SPiotr Jasiukajtis 	    "1:\n\t"
11825c28e83SPiotr Jasiukajtis 	    "subcc  %0,%2,%%g0\n\t"
11925c28e83SPiotr Jasiukajtis 	    "bge,pn %%xcc,1f\n\t"
12025c28e83SPiotr Jasiukajtis 	    "nop\n\t"
12125c28e83SPiotr Jasiukajtis 	    "or	    %%g0,2,%0\n\t"
12225c28e83SPiotr Jasiukajtis 	    "ba	    2f\n\t"
12325c28e83SPiotr Jasiukajtis 	    "nop\n\t"
12425c28e83SPiotr Jasiukajtis 	    "1:\n\t"
12525c28e83SPiotr Jasiukajtis 	    "andncc %0,%2,%0\n\t"
12625c28e83SPiotr Jasiukajtis 	    "bne,pn %%xcc,1f\n\t"
12725c28e83SPiotr Jasiukajtis 	    "nop\n\t"
12825c28e83SPiotr Jasiukajtis 	    "or	    %%g0,3,%0\n\t"
12925c28e83SPiotr Jasiukajtis 	    "ba	    2f\n\t"
13025c28e83SPiotr Jasiukajtis 	    "nop\n\t"
13125c28e83SPiotr Jasiukajtis 	    "1:\n\t"
13225c28e83SPiotr Jasiukajtis 	    "sethi  %%hi(0x00080000),%2\n\t"
13325c28e83SPiotr Jasiukajtis 	    "sllx   %2,32,%2\n\t"
13425c28e83SPiotr Jasiukajtis 	    "andcc  %0,%2,%%g0\n\t"
13525c28e83SPiotr Jasiukajtis 	    "or	    %%g0,4,%0\n\t"
13625c28e83SPiotr Jasiukajtis 	    "bne,pt %%xcc,2f\n\t"
13725c28e83SPiotr Jasiukajtis 	    "nop\n\t"
13825c28e83SPiotr Jasiukajtis 	    "or	    %%g0,5,%0\n\t"
13925c28e83SPiotr Jasiukajtis 	    "2:\n\t"
14025c28e83SPiotr Jasiukajtis 	    : "=r" (ret), "=m" (dint), "=r" (tmp), "+e" (d)
14125c28e83SPiotr Jasiukajtis 	    :
14225c28e83SPiotr Jasiukajtis 	    : "cc");
14325c28e83SPiotr Jasiukajtis 
14425c28e83SPiotr Jasiukajtis 	return (ret);
14525c28e83SPiotr Jasiukajtis }
14625c28e83SPiotr Jasiukajtis 
147*7f11fd00SRichard Lowe extern __GNU_INLINE float
__inline_sqrtf(float f)14825c28e83SPiotr Jasiukajtis __inline_sqrtf(float f)
14925c28e83SPiotr Jasiukajtis {
15025c28e83SPiotr Jasiukajtis 	float ret;
15125c28e83SPiotr Jasiukajtis 
15225c28e83SPiotr Jasiukajtis 	__asm__ __volatile__("fsqrts %1,%0\n\t" : "=f" (ret) : "f" (f));
15325c28e83SPiotr Jasiukajtis 	return (ret);
15425c28e83SPiotr Jasiukajtis }
15525c28e83SPiotr Jasiukajtis 
156*7f11fd00SRichard Lowe extern __GNU_INLINE double
__inline_sqrt(double d)15725c28e83SPiotr Jasiukajtis __inline_sqrt(double d)
15825c28e83SPiotr Jasiukajtis {
15925c28e83SPiotr Jasiukajtis 	double ret;
16025c28e83SPiotr Jasiukajtis 
16125c28e83SPiotr Jasiukajtis 	__asm__ __volatile__("fsqrtd %1,%0\n\t" : "=f" (ret) : "f" (d));
16225c28e83SPiotr Jasiukajtis 	return (ret);
16325c28e83SPiotr Jasiukajtis }
16425c28e83SPiotr Jasiukajtis 
165*7f11fd00SRichard Lowe extern __GNU_INLINE int
__swapEX(int i)16625c28e83SPiotr Jasiukajtis __swapEX(int i)
16725c28e83SPiotr Jasiukajtis {
16825c28e83SPiotr Jasiukajtis 	int ret;
16925c28e83SPiotr Jasiukajtis 	uint32_t fsr;
17025c28e83SPiotr Jasiukajtis 	uint64_t tmp1, tmp2;
17125c28e83SPiotr Jasiukajtis 
17225c28e83SPiotr Jasiukajtis 	__asm__ __volatile__(
17325c28e83SPiotr Jasiukajtis 	    "and  %4,0x1f,%2\n\t"
17425c28e83SPiotr Jasiukajtis 	    "sll  %2,5,%2\n\t"	/* shift input to aexc bit location */
17525c28e83SPiotr Jasiukajtis 	    ".volatile\n\t"
17625c28e83SPiotr Jasiukajtis 	    "st   %%fsr,%1\n\t"
17725c28e83SPiotr Jasiukajtis 	    "ld	  %1,%0\n\t"	/* %0 = fsr */
17825c28e83SPiotr Jasiukajtis 	    "andn %0,0x3e0,%3\n\t"
17925c28e83SPiotr Jasiukajtis 	    "or   %2,%3,%2\n\t"	/* %2 = new fsr */
18025c28e83SPiotr Jasiukajtis 	    "st	  %2,%1\n\t"
18125c28e83SPiotr Jasiukajtis 	    "ld	  %1,%%fsr\n\t"
18225c28e83SPiotr Jasiukajtis 	    "srl  %0,5,%0\n\t"
18325c28e83SPiotr Jasiukajtis 	    "and  %0,0x1f,%0\n\t"
18425c28e83SPiotr Jasiukajtis 	    ".nonvolatile\n\t"
18525c28e83SPiotr Jasiukajtis 	    : "=r" (ret), "=m" (fsr), "=r" (tmp1), "=r" (tmp2)
18625c28e83SPiotr Jasiukajtis 	    : "r" (i)
18725c28e83SPiotr Jasiukajtis 	    : "cc");
18825c28e83SPiotr Jasiukajtis 
18925c28e83SPiotr Jasiukajtis 	return (ret);
19025c28e83SPiotr Jasiukajtis }
19125c28e83SPiotr Jasiukajtis 
19225c28e83SPiotr Jasiukajtis /*
19325c28e83SPiotr Jasiukajtis  * On the SPARC, __swapRP is a no-op; always return 0 for backward
19425c28e83SPiotr Jasiukajtis  * compatibility
19525c28e83SPiotr Jasiukajtis  */
19625c28e83SPiotr Jasiukajtis /* ARGSUSED */
197*7f11fd00SRichard Lowe extern __GNU_INLINE enum fp_precision_type
__swapRP(enum fp_precision_type i)19825c28e83SPiotr Jasiukajtis __swapRP(enum fp_precision_type i)
19925c28e83SPiotr Jasiukajtis {
20025c28e83SPiotr Jasiukajtis 	return (0);
20125c28e83SPiotr Jasiukajtis }
20225c28e83SPiotr Jasiukajtis 
203*7f11fd00SRichard Lowe extern __GNU_INLINE enum fp_direction_type
__swapRD(enum fp_direction_type d)20425c28e83SPiotr Jasiukajtis __swapRD(enum fp_direction_type d)
20525c28e83SPiotr Jasiukajtis {
20625c28e83SPiotr Jasiukajtis 	enum fp_direction_type ret;
20725c28e83SPiotr Jasiukajtis 	uint32_t fsr;
20825c28e83SPiotr Jasiukajtis 	uint64_t tmp1, tmp2, tmp3;
20925c28e83SPiotr Jasiukajtis 
21025c28e83SPiotr Jasiukajtis 	__asm__ __volatile__(
21125c28e83SPiotr Jasiukajtis 	    "and   %5,0x3,%0\n\t"
21225c28e83SPiotr Jasiukajtis 	    "sll   %0,30,%2\n\t"	/* shift input to RD bit location */
21325c28e83SPiotr Jasiukajtis 	    ".volatile\n\t"
21425c28e83SPiotr Jasiukajtis 	    "st    %%fsr,%1\n\t"
21525c28e83SPiotr Jasiukajtis 	    "ld	   %1,%0\n\t"		/* %0 = fsr */
21625c28e83SPiotr Jasiukajtis 	    /* mask of rounding direction bits */
21725c28e83SPiotr Jasiukajtis 	    "sethi %%hi(0xc0000000),%4\n\t"
21825c28e83SPiotr Jasiukajtis 	    "andn  %0,%4,%3\n\t"
21925c28e83SPiotr Jasiukajtis 	    "or    %2,%3,%2\n\t"	/* %2 = new fsr */
22025c28e83SPiotr Jasiukajtis 	    "st	   %2,%1\n\t"
22125c28e83SPiotr Jasiukajtis 	    "ld	   %1,%%fsr\n\t"
22225c28e83SPiotr Jasiukajtis 	    "srl   %0,30,%0\n\t"
22325c28e83SPiotr Jasiukajtis 	    "and   %0,0x3,%0\n\t"
22425c28e83SPiotr Jasiukajtis 	    ".nonvolatile\n\t"
22525c28e83SPiotr Jasiukajtis 	    : "=r" (ret), "=m" (fsr), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3)
22625c28e83SPiotr Jasiukajtis 	    : "r" (d)
22725c28e83SPiotr Jasiukajtis 	    : "cc");
22825c28e83SPiotr Jasiukajtis 
22925c28e83SPiotr Jasiukajtis 	return (ret);
23025c28e83SPiotr Jasiukajtis }
23125c28e83SPiotr Jasiukajtis 
232*7f11fd00SRichard Lowe extern __GNU_INLINE int
__swapTE(int i)23325c28e83SPiotr Jasiukajtis __swapTE(int i)
23425c28e83SPiotr Jasiukajtis {
23525c28e83SPiotr Jasiukajtis 	int ret;
23625c28e83SPiotr Jasiukajtis 	uint32_t fsr;
23725c28e83SPiotr Jasiukajtis 	uint64_t tmp1, tmp2, tmp3;
23825c28e83SPiotr Jasiukajtis 
23925c28e83SPiotr Jasiukajtis 	__asm__ __volatile__(
24025c28e83SPiotr Jasiukajtis 	    "and   %5,0x1f,%0\n\t"
24125c28e83SPiotr Jasiukajtis 	    "sll   %0,23,%2\n\t"	/* shift input to TEM bit location */
24225c28e83SPiotr Jasiukajtis 	    ".volatile\n\t"
24325c28e83SPiotr Jasiukajtis 	    "st    %%fsr,%1\n\t"
24425c28e83SPiotr Jasiukajtis 	    "ld	   %1,%0\n\t"		/* %0 = fsr */
24525c28e83SPiotr Jasiukajtis 	    /* mask of TEM (Trap Enable Mode bits) */
24625c28e83SPiotr Jasiukajtis 	    "sethi %%hi(0x0f800000),%4\n\t"
24725c28e83SPiotr Jasiukajtis 	    "andn  %0,%4,%3\n\t"
24825c28e83SPiotr Jasiukajtis 	    "or    %2,%3,%2\n\t"	/* %2 = new fsr */
24925c28e83SPiotr Jasiukajtis 	    "st	   %2,%1\n\t"
25025c28e83SPiotr Jasiukajtis 	    "ld	   %1,%%fsr\n\t"
25125c28e83SPiotr Jasiukajtis 	    "srl   %0,23,%0\n\t"
25225c28e83SPiotr Jasiukajtis 	    "and   %0,0x1f,%0\n\t"
25325c28e83SPiotr Jasiukajtis 	    ".nonvolatile\n\t"
25425c28e83SPiotr Jasiukajtis 	    : "=r" (ret), "=m" (fsr), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3)
25525c28e83SPiotr Jasiukajtis 	    : "r" (i)
25625c28e83SPiotr Jasiukajtis 	    : "cc");
25725c28e83SPiotr Jasiukajtis 
25825c28e83SPiotr Jasiukajtis 	return (ret);
25925c28e83SPiotr Jasiukajtis }
26025c28e83SPiotr Jasiukajtis 
26125c28e83SPiotr Jasiukajtis 
262*7f11fd00SRichard Lowe extern __GNU_INLINE double
sqrt(double d)26325c28e83SPiotr Jasiukajtis sqrt(double d)
26425c28e83SPiotr Jasiukajtis {
26525c28e83SPiotr Jasiukajtis 	return (__inline_sqrt(d));
26625c28e83SPiotr Jasiukajtis }
26725c28e83SPiotr Jasiukajtis 
268*7f11fd00SRichard Lowe extern __GNU_INLINE float
sqrtf(float f)26925c28e83SPiotr Jasiukajtis sqrtf(float f)
27025c28e83SPiotr Jasiukajtis {
27125c28e83SPiotr Jasiukajtis 	return (__inline_sqrtf(f));
27225c28e83SPiotr Jasiukajtis }
27325c28e83SPiotr Jasiukajtis 
274*7f11fd00SRichard Lowe extern __GNU_INLINE double
fabs(double d)27525c28e83SPiotr Jasiukajtis fabs(double d)
27625c28e83SPiotr Jasiukajtis {
27725c28e83SPiotr Jasiukajtis 	double ret;
27825c28e83SPiotr Jasiukajtis 
27925c28e83SPiotr Jasiukajtis 	__asm__ __volatile__("fabsd %1,%0\n\t" : "=e" (ret) : "e" (d));
28025c28e83SPiotr Jasiukajtis 	return (ret);
28125c28e83SPiotr Jasiukajtis }
28225c28e83SPiotr Jasiukajtis 
283*7f11fd00SRichard Lowe extern __GNU_INLINE float
fabsf(float f)28425c28e83SPiotr Jasiukajtis fabsf(float f)
28525c28e83SPiotr Jasiukajtis {
28625c28e83SPiotr Jasiukajtis 	float ret;
28725c28e83SPiotr Jasiukajtis 
28825c28e83SPiotr Jasiukajtis 	__asm__ __volatile__("fabss %1,%0\n\t" : "=f" (ret) : "f" (f));
28925c28e83SPiotr Jasiukajtis 	return (ret);
29025c28e83SPiotr Jasiukajtis }
29125c28e83SPiotr Jasiukajtis 
29225c28e83SPiotr Jasiukajtis #ifdef __cplusplus
29325c28e83SPiotr Jasiukajtis }
29425c28e83SPiotr Jasiukajtis #endif
29525c28e83SPiotr Jasiukajtis 
29625c28e83SPiotr Jasiukajtis #endif  /* __GNUC__ */
29725c28e83SPiotr Jasiukajtis 
29825c28e83SPiotr Jasiukajtis #endif /* _LIBM_INLINES_H */