xref: /illumos-gate/usr/src/lib/libc/inc/base_inlines.h (revision dd72704bd9e794056c558153663c739e2012d721)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #ifndef	_BASE_INLINES_H
28 #define	_BASE_INLINES_H
29 
30 #include <sys/ccompile.h>
31 #include <sys/types.h>
32 
33 #if !defined(__lint) && defined(__GNUC__)
34 
35 /*
36  * At the moment these inlines exist only for sparc and sparcv9 and these
37  * functions are implemented in C for x86.
38  */
39 
40 #if defined(__sparc)
41 extern __GNU_INLINE double
42 __mul_set(double x, double y, int *pe)
43 {
44 	double __result;
45 	uint32_t __fsr;
46 	uint32_t *__addr = &__fsr;
47 
48 	__asm__ __volatile__(
49 	    "fmuld %4, %5, %0\n\t"
50 	    "st %%fsr, %3\n\t"
51 	    "ld %3, %2\n\t"
52 	    "and %2, 1, %2\n\t"
53 	    "st %2, %1"
54 	    : "=&e" (__result), "=m" (*pe), "=r" (__fsr), "=m" (*__addr)
55 	    : "e" (x), "e" (y));
56 	return (__result);
57 }
58 #endif	/* __sparc */
59 
60 #if defined(__sparc)
61 extern __GNU_INLINE double
62 __div_set(double x, double y, int *pe)
63 {
64 	double __result;
65 	uint32_t __fsr;
66 	uint32_t *__addr = &__fsr;
67 
68 	__asm__ __volatile__(
69 	    "fdivd %4, %5, %0\n\t"
70 	    "st %%fsr, %3\n\t"
71 	    "ld %3, %2\n\t"
72 	    "and %2, 1, %2\n\t"
73 	    "st %2, %1"
74 	    : "=&e" (__result), "=m" (*pe), "=r" (__fsr), "=m" (*__addr)
75 	    : "e" (x), "e" (y));
76 	return (__result);
77 }
78 #endif	/* __sparc */
79 
80 #if defined(__sparc)
81 extern __GNU_INLINE double
82 __dabs(double *x)
83 {
84 	double __result;
85 
86 	__asm__ __volatile__(
87 #if defined(__sparcv9)
88 	    "fabsd %1, %0"
89 #else
90 	    "fabss %1, %0"
91 #endif
92 	    : "=e" (__result)
93 	    : "0" (*x));
94 	return (__result);
95 }
96 #endif	/* __sparc */
97 
98 #if defined(__sparc)
99 extern  __GNU_INLINE void
100 __get_ieee_flags(__ieee_flags_type *b)
101 {
102 	uint32_t __fsr;
103 
104 	/*
105 	 * It's preferable to let the assembler insert the nops as
106 	 * needed; however, it warns as it does so.  Add them here for now.
107 	 */
108 	__asm__ __volatile__(
109 	    "st %%fsr, %0\n\t"
110 	    "st %%g0, %1\n\t"
111 	    "ld %1, %%fsr\n\t"
112 	    "nop; nop; nop"
113 	    : "=m" (*b), "=m" (__fsr));
114 }
115 #endif	/* __sparc */
116 
117 #if defined(__sparc)
118 extern __GNU_INLINE void
119 __set_ieee_flags(__ieee_flags_type *b)
120 {
121 	/*
122 	 * It's preferable to let the assembler insert the nops as
123 	 * needed; however, it warns as it does so.  Add them here for now.
124 	 */
125 	__asm__ __volatile__(
126 	    "ld %0, %%fsr\n\t"
127 	    "nop; nop; nop"
128 	    : /* no outputs */
129 	    : "m" (*b));
130 }
131 #endif	/* __sparc */
132 
133 #endif	/* !__lint && __GNUC__ */
134 
135 #endif	/* _BASE_INLINES_H */
136