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 * This file is intended to contain gcc-style inline assembly that corresponds
37 * to base.il for all architectures.  At the moment these inlines exist only
38 * for sparc and sparcv9 and these functions are implemented in C for x86.
39 * They should be inlined here for gcc if a new x86 base.il is created.
40 */
41
42#if defined(__sparc)
43extern __GNU_INLINE double
44__mul_set(double x, double y, int *pe)
45{
46	double __result;
47	uint32_t __fsr;
48	uint32_t *__addr = &__fsr;
49
50	__asm__ __volatile__(
51	    "fmuld %4, %5, %0\n\t"
52	    "st %%fsr, %3\n\t"
53	    "ld %3, %2\n\t"
54	    "and %2, 1, %2\n\t"
55	    "st %2, %1"
56	    : "=&e" (__result), "=m" (*pe), "=r" (__fsr), "=m" (*__addr)
57	    : "e" (x), "e" (y));
58	return (__result);
59}
60#endif	/* __sparc */
61
62#if defined(__sparc)
63extern __GNU_INLINE double
64__div_set(double x, double y, int *pe)
65{
66	double __result;
67	uint32_t __fsr;
68	uint32_t *__addr = &__fsr;
69
70	__asm__ __volatile__(
71	    "fdivd %4, %5, %0\n\t"
72	    "st %%fsr, %3\n\t"
73	    "ld %3, %2\n\t"
74	    "and %2, 1, %2\n\t"
75	    "st %2, %1"
76	    : "=&e" (__result), "=m" (*pe), "=r" (__fsr), "=m" (*__addr)
77	    : "e" (x), "e" (y));
78	return (__result);
79}
80#endif	/* __sparc */
81
82#if defined(__sparc)
83extern __GNU_INLINE double
84__dabs(double *x)
85{
86	double __result;
87
88	__asm__ __volatile__(
89#if defined(__sparcv9)
90	    "fabsd %1, %0"
91#else
92	    "fabss %1, %0"
93#endif
94	    : "=e" (__result)
95	    : "0" (*x));
96	return (__result);
97}
98#endif	/* __sparc */
99
100#if defined(__sparc)
101extern  __GNU_INLINE void
102__get_ieee_flags(__ieee_flags_type *b)
103{
104	uint32_t __fsr;
105
106	/*
107	 * It's preferable to let the assembler insert the nops as
108	 * needed; however, it warns as it does so.  Add them here for now.
109	 */
110	__asm__ __volatile__(
111	    "st %%fsr, %0\n\t"
112	    "st %%g0, %1\n\t"
113	    "ld %1, %%fsr\n\t"
114	    "nop; nop; nop"
115	    : "=m" (*b), "=m" (__fsr));
116}
117#endif	/* __sparc */
118
119#if defined(__sparc)
120extern __GNU_INLINE void
121__set_ieee_flags(__ieee_flags_type *b)
122{
123	/*
124	 * It's preferable to let the assembler insert the nops as
125	 * needed; however, it warns as it does so.  Add them here for now.
126	 */
127	__asm__ __volatile__(
128	    "ld %0, %%fsr\n\t"
129	    "nop; nop; nop"
130	    : /* no outputs */
131	    : "m" (*b));
132}
133#endif	/* __sparc */
134
135#endif	/* !__lint && __GNUC__ */
136
137#endif	/* _BASE_INLINES_H */
138