1*25c28e83SPiotr Jasiukajtis /*
2*25c28e83SPiotr Jasiukajtis  * CDDL HEADER START
3*25c28e83SPiotr Jasiukajtis  *
4*25c28e83SPiotr Jasiukajtis  * The contents of this file are subject to the terms of the
5*25c28e83SPiotr Jasiukajtis  * Common Development and Distribution License (the "License").
6*25c28e83SPiotr Jasiukajtis  * You may not use this file except in compliance with the License.
7*25c28e83SPiotr Jasiukajtis  *
8*25c28e83SPiotr Jasiukajtis  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*25c28e83SPiotr Jasiukajtis  * or http://www.opensolaris.org/os/licensing.
10*25c28e83SPiotr Jasiukajtis  * See the License for the specific language governing permissions
11*25c28e83SPiotr Jasiukajtis  * and limitations under the License.
12*25c28e83SPiotr Jasiukajtis  *
13*25c28e83SPiotr Jasiukajtis  * When distributing Covered Code, include this CDDL HEADER in each
14*25c28e83SPiotr Jasiukajtis  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*25c28e83SPiotr Jasiukajtis  * If applicable, add the following below this CDDL HEADER, with the
16*25c28e83SPiotr Jasiukajtis  * fields enclosed by brackets "[]" replaced with your own identifying
17*25c28e83SPiotr Jasiukajtis  * information: Portions Copyright [yyyy] [name of copyright owner]
18*25c28e83SPiotr Jasiukajtis  *
19*25c28e83SPiotr Jasiukajtis  * CDDL HEADER END
20*25c28e83SPiotr Jasiukajtis  */
21*25c28e83SPiotr Jasiukajtis 
22*25c28e83SPiotr Jasiukajtis /*
23*25c28e83SPiotr Jasiukajtis  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
24*25c28e83SPiotr Jasiukajtis  */
25*25c28e83SPiotr Jasiukajtis /*
26*25c28e83SPiotr Jasiukajtis  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
27*25c28e83SPiotr Jasiukajtis  * Use is subject to license terms.
28*25c28e83SPiotr Jasiukajtis  */
29*25c28e83SPiotr Jasiukajtis 
30*25c28e83SPiotr Jasiukajtis /*
31*25c28e83SPiotr Jasiukajtis  * Copyright 2011, Richard Lowe.
32*25c28e83SPiotr Jasiukajtis  */
33*25c28e83SPiotr Jasiukajtis 
34*25c28e83SPiotr Jasiukajtis /* Functions in this file are duplicated in locallibm.il.  Keep them in sync */
35*25c28e83SPiotr Jasiukajtis 
36*25c28e83SPiotr Jasiukajtis #ifndef _LIBM_INLINES_H
37*25c28e83SPiotr Jasiukajtis #define	_LIBM_INLINES_H
38*25c28e83SPiotr Jasiukajtis 
39*25c28e83SPiotr Jasiukajtis #ifdef __GNUC__
40*25c28e83SPiotr Jasiukajtis 
41*25c28e83SPiotr Jasiukajtis #ifdef __cplusplus
42*25c28e83SPiotr Jasiukajtis extern "C" {
43*25c28e83SPiotr Jasiukajtis #endif
44*25c28e83SPiotr Jasiukajtis 
45*25c28e83SPiotr Jasiukajtis #include <sys/types.h>
46*25c28e83SPiotr Jasiukajtis #include <sys/ieeefp.h>
47*25c28e83SPiotr Jasiukajtis 
48*25c28e83SPiotr Jasiukajtis extern __inline__ float
49*25c28e83SPiotr Jasiukajtis __inline_sqrtf(float a)
50*25c28e83SPiotr Jasiukajtis {
51*25c28e83SPiotr Jasiukajtis 	float ret;
52*25c28e83SPiotr Jasiukajtis 
53*25c28e83SPiotr Jasiukajtis 	__asm__ __volatile__("sqrtss %1, %0\n\t" : "=x" (ret) : "x" (a));
54*25c28e83SPiotr Jasiukajtis 	return (ret);
55*25c28e83SPiotr Jasiukajtis }
56*25c28e83SPiotr Jasiukajtis 
57*25c28e83SPiotr Jasiukajtis extern __inline__ double
58*25c28e83SPiotr Jasiukajtis __inline_sqrt(double a)
59*25c28e83SPiotr Jasiukajtis {
60*25c28e83SPiotr Jasiukajtis 	double ret;
61*25c28e83SPiotr Jasiukajtis 
62*25c28e83SPiotr Jasiukajtis 	__asm__ __volatile__("sqrtsd %1, %0\n\t" : "=x" (ret) : "x" (a));
63*25c28e83SPiotr Jasiukajtis 	return (ret);
64*25c28e83SPiotr Jasiukajtis }
65*25c28e83SPiotr Jasiukajtis 
66*25c28e83SPiotr Jasiukajtis extern __inline__ double
67*25c28e83SPiotr Jasiukajtis __ieee754_sqrt(double a)
68*25c28e83SPiotr Jasiukajtis {
69*25c28e83SPiotr Jasiukajtis 	return (__inline_sqrt(a));
70*25c28e83SPiotr Jasiukajtis }
71*25c28e83SPiotr Jasiukajtis 
72*25c28e83SPiotr Jasiukajtis /*
73*25c28e83SPiotr Jasiukajtis  * 00 - 24 bits
74*25c28e83SPiotr Jasiukajtis  * 01 - reserved
75*25c28e83SPiotr Jasiukajtis  * 10 - 53 bits
76*25c28e83SPiotr Jasiukajtis  * 11 - 64 bits
77*25c28e83SPiotr Jasiukajtis  */
78*25c28e83SPiotr Jasiukajtis extern __inline__ int
79*25c28e83SPiotr Jasiukajtis __swapRP(int i)
80*25c28e83SPiotr Jasiukajtis {
81*25c28e83SPiotr Jasiukajtis 	int ret;
82*25c28e83SPiotr Jasiukajtis 	uint16_t cw;
83*25c28e83SPiotr Jasiukajtis 
84*25c28e83SPiotr Jasiukajtis 	__asm__ __volatile__("fstcw %0\n\t" : "=m" (cw));
85*25c28e83SPiotr Jasiukajtis 
86*25c28e83SPiotr Jasiukajtis 	ret = (cw >> 8) & 0x3;
87*25c28e83SPiotr Jasiukajtis 	cw = (cw & 0xfcff) | ((i & 0x3) << 8);
88*25c28e83SPiotr Jasiukajtis 
89*25c28e83SPiotr Jasiukajtis 	__asm__ __volatile__("fldcw %0\n\t" : : "m" (cw));
90*25c28e83SPiotr Jasiukajtis 
91*25c28e83SPiotr Jasiukajtis 	return (ret);
92*25c28e83SPiotr Jasiukajtis }
93*25c28e83SPiotr Jasiukajtis 
94*25c28e83SPiotr Jasiukajtis /*
95*25c28e83SPiotr Jasiukajtis  * 00 - Round to nearest, with even preferred
96*25c28e83SPiotr Jasiukajtis  * 01 - Round down
97*25c28e83SPiotr Jasiukajtis  * 10 - Round up
98*25c28e83SPiotr Jasiukajtis  * 11 - Chop
99*25c28e83SPiotr Jasiukajtis  */
100*25c28e83SPiotr Jasiukajtis extern __inline__ enum fp_direction_type
101*25c28e83SPiotr Jasiukajtis __swap87RD(enum fp_direction_type i)
102*25c28e83SPiotr Jasiukajtis {
103*25c28e83SPiotr Jasiukajtis 	int ret;
104*25c28e83SPiotr Jasiukajtis 	uint16_t cw;
105*25c28e83SPiotr Jasiukajtis 
106*25c28e83SPiotr Jasiukajtis 	__asm__ __volatile__("fstcw %0\n\t" : "=m" (cw));
107*25c28e83SPiotr Jasiukajtis 
108*25c28e83SPiotr Jasiukajtis 	ret = (cw >> 10) & 0x3;
109*25c28e83SPiotr Jasiukajtis 	cw = (cw & 0xf3ff) | ((i & 0x3) << 10);
110*25c28e83SPiotr Jasiukajtis 
111*25c28e83SPiotr Jasiukajtis 	__asm__ __volatile__("fldcw %0\n\t" : : "m" (cw));
112*25c28e83SPiotr Jasiukajtis 
113*25c28e83SPiotr Jasiukajtis 	return (ret);
114*25c28e83SPiotr Jasiukajtis }
115*25c28e83SPiotr Jasiukajtis 
116*25c28e83SPiotr Jasiukajtis extern __inline__ int
117*25c28e83SPiotr Jasiukajtis abs(int i)
118*25c28e83SPiotr Jasiukajtis {
119*25c28e83SPiotr Jasiukajtis 	int ret;
120*25c28e83SPiotr Jasiukajtis 	__asm__ __volatile__(
121*25c28e83SPiotr Jasiukajtis 	    "movl    %1, %0\n\t"
122*25c28e83SPiotr Jasiukajtis 	    "negl    %1\n\t"
123*25c28e83SPiotr Jasiukajtis 	    "cmovnsl %1, %0\n\t"
124*25c28e83SPiotr Jasiukajtis 	    : "=r" (ret), "+r" (i)
125*25c28e83SPiotr Jasiukajtis 	    :
126*25c28e83SPiotr Jasiukajtis 	    : "cc");
127*25c28e83SPiotr Jasiukajtis 	return (ret);
128*25c28e83SPiotr Jasiukajtis }
129*25c28e83SPiotr Jasiukajtis 
130*25c28e83SPiotr Jasiukajtis extern __inline__ double
131*25c28e83SPiotr Jasiukajtis copysign(double d1, double d2)
132*25c28e83SPiotr Jasiukajtis {
133*25c28e83SPiotr Jasiukajtis 	double tmpd;
134*25c28e83SPiotr Jasiukajtis 
135*25c28e83SPiotr Jasiukajtis 	__asm__ __volatile__(
136*25c28e83SPiotr Jasiukajtis 	    "movd %3, %1\n\t"
137*25c28e83SPiotr Jasiukajtis 	    "andpd %1, %0\n\t"
138*25c28e83SPiotr Jasiukajtis 	    "andnpd %2, %1\n\t"
139*25c28e83SPiotr Jasiukajtis 	    "orpd %1, %0\n\t"
140*25c28e83SPiotr Jasiukajtis 	    : "+&x" (d1), "=&x" (tmpd)
141*25c28e83SPiotr Jasiukajtis 	    : "x" (d2), "r" (0x7fffffffffffffff));
142*25c28e83SPiotr Jasiukajtis 
143*25c28e83SPiotr Jasiukajtis 	return (d1);
144*25c28e83SPiotr Jasiukajtis }
145*25c28e83SPiotr Jasiukajtis 
146*25c28e83SPiotr Jasiukajtis extern __inline__ double
147*25c28e83SPiotr Jasiukajtis fabs(double d)
148*25c28e83SPiotr Jasiukajtis {
149*25c28e83SPiotr Jasiukajtis 	double tmp;
150*25c28e83SPiotr Jasiukajtis 
151*25c28e83SPiotr Jasiukajtis 	__asm__ __volatile__(
152*25c28e83SPiotr Jasiukajtis 	    "movd  %2, %1\n\t"
153*25c28e83SPiotr Jasiukajtis 	    "andpd %1, %0"
154*25c28e83SPiotr Jasiukajtis 	    : "+x" (d), "=&x" (tmp)
155*25c28e83SPiotr Jasiukajtis 	    : "r" (0x7fffffffffffffff));
156*25c28e83SPiotr Jasiukajtis 
157*25c28e83SPiotr Jasiukajtis 	return (d);
158*25c28e83SPiotr Jasiukajtis }
159*25c28e83SPiotr Jasiukajtis 
160*25c28e83SPiotr Jasiukajtis extern __inline__ float
161*25c28e83SPiotr Jasiukajtis fabsf(float d)
162*25c28e83SPiotr Jasiukajtis {
163*25c28e83SPiotr Jasiukajtis 	__asm__ __volatile__(
164*25c28e83SPiotr Jasiukajtis 	    "andpd %1, %0"
165*25c28e83SPiotr Jasiukajtis 	    : "+x" (d)
166*25c28e83SPiotr Jasiukajtis 	    : "x" (0x7fffffff));
167*25c28e83SPiotr Jasiukajtis 
168*25c28e83SPiotr Jasiukajtis 	return (d);
169*25c28e83SPiotr Jasiukajtis }
170*25c28e83SPiotr Jasiukajtis 
171*25c28e83SPiotr Jasiukajtis extern __inline__ int
172*25c28e83SPiotr Jasiukajtis finite(double d)
173*25c28e83SPiotr Jasiukajtis {
174*25c28e83SPiotr Jasiukajtis 	long ret = 0x7fffffffffffffff;
175*25c28e83SPiotr Jasiukajtis 	uint64_t tmp;
176*25c28e83SPiotr Jasiukajtis 
177*25c28e83SPiotr Jasiukajtis 	__asm__ __volatile__(
178*25c28e83SPiotr Jasiukajtis 	    "movq %2, %1\n\t"
179*25c28e83SPiotr Jasiukajtis 	    "andq %1, %0\n\t"
180*25c28e83SPiotr Jasiukajtis 	    "movq $0x7ff0000000000000, %1\n\t"
181*25c28e83SPiotr Jasiukajtis 	    "subq %1, %0\n\t"
182*25c28e83SPiotr Jasiukajtis 	    "shrq $63, %0\n\t"
183*25c28e83SPiotr Jasiukajtis 	    : "+r" (ret), "=r" (tmp)
184*25c28e83SPiotr Jasiukajtis 	    : "x" (d)
185*25c28e83SPiotr Jasiukajtis 	    : "cc");
186*25c28e83SPiotr Jasiukajtis 
187*25c28e83SPiotr Jasiukajtis 	return (ret);
188*25c28e83SPiotr Jasiukajtis }
189*25c28e83SPiotr Jasiukajtis 
190*25c28e83SPiotr Jasiukajtis extern __inline__ int
191*25c28e83SPiotr Jasiukajtis signbit(double d)
192*25c28e83SPiotr Jasiukajtis {
193*25c28e83SPiotr Jasiukajtis 	long ret;
194*25c28e83SPiotr Jasiukajtis 	__asm__ __volatile__(
195*25c28e83SPiotr Jasiukajtis 	    "movmskpd %1, %0\n\t"
196*25c28e83SPiotr Jasiukajtis 	    "andq     $1, %0\n\t"
197*25c28e83SPiotr Jasiukajtis 	    : "=r" (ret)
198*25c28e83SPiotr Jasiukajtis 	    : "x" (d)
199*25c28e83SPiotr Jasiukajtis 	    : "cc");
200*25c28e83SPiotr Jasiukajtis 	return (ret);
201*25c28e83SPiotr Jasiukajtis }
202*25c28e83SPiotr Jasiukajtis 
203*25c28e83SPiotr Jasiukajtis extern __inline__ double
204*25c28e83SPiotr Jasiukajtis sqrt(double d)
205*25c28e83SPiotr Jasiukajtis {
206*25c28e83SPiotr Jasiukajtis 	return (__inline_sqrt(d));
207*25c28e83SPiotr Jasiukajtis }
208*25c28e83SPiotr Jasiukajtis 
209*25c28e83SPiotr Jasiukajtis extern __inline__ float
210*25c28e83SPiotr Jasiukajtis sqrtf(float f)
211*25c28e83SPiotr Jasiukajtis {
212*25c28e83SPiotr Jasiukajtis 	return (__inline_sqrtf(f));
213*25c28e83SPiotr Jasiukajtis }
214*25c28e83SPiotr Jasiukajtis 
215*25c28e83SPiotr Jasiukajtis #ifdef __cplusplus
216*25c28e83SPiotr Jasiukajtis }
217*25c28e83SPiotr Jasiukajtis #endif
218*25c28e83SPiotr Jasiukajtis 
219*25c28e83SPiotr Jasiukajtis #endif  /* __GNUC__ */
220*25c28e83SPiotr Jasiukajtis 
221*25c28e83SPiotr Jasiukajtis #endif /* _LIBM_INLINES_H */
222