OpenSolaris_b135/lib/libc/inc/base_inlines.h
/*
* 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 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _BASE_INLINES_H
#define _BASE_INLINES_H
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/types.h>
#if !defined(__lint) && defined(__GNUC__)
/*
* This file is intended to contain gcc-style inline assembly that corresponds
* to base.il for all architectures. At the moment these inlines exist only
* for sparc and sparcv9 and these functions are implemented in C for x86.
* They should be inlined here for gcc if a new x86 base.il is created.
*/
#if defined(__sparc)
extern __inline__ double
__mul_set(double x, double y, int *pe)
{
double __result;
uint32_t __fsr;
uint32_t *__addr = &__fsr;
__asm__ __volatile__(
"fmuld %4, %5, %0\n\t"
"st %%fsr, %3\n\t"
"ld %3, %2\n\t"
"and %2, 1, %2\n\t"
"st %2, %1"
: "=&e" (__result), "=m" (*pe), "=r" (__fsr), "=m" (*__addr)
: "e" (x), "e" (y));
return (__result);
}
#endif /* __sparc */
#if defined(__sparc)
extern __inline__ double
__div_set(double x, double y, int *pe)
{
double __result;
uint32_t __fsr;
uint32_t *__addr = &__fsr;
__asm__ __volatile__(
"fdivd %4, %5, %0\n\t"
"st %%fsr, %3\n\t"
"ld %3, %2\n\t"
"and %2, 1, %2\n\t"
"st %2, %1"
: "=&e" (__result), "=m" (*pe), "=r" (__fsr), "=m" (*__addr)
: "e" (x), "e" (y));
return (__result);
}
#endif /* __sparc */
#if defined(__sparc)
extern __inline__ double
__dabs(double *x)
{
double __result;
__asm__ __volatile__(
#if defined(__sparcv9)
"fabsd %1, %0"
#else
"fabss %1, %0"
#endif
: "=e" (__result)
: "0" (*x));
return (__result);
}
#endif /* __sparc */
#if defined(__sparc)
extern __inline__ void
__get_ieee_flags(__ieee_flags_type *b)
{
uint32_t __fsr;
/*
* It's preferable to let the assembler insert the nops as
* needed; however, it warns as it does so. Add them here for now.
*/
__asm__ __volatile__(
"st %%fsr, %0\n\t"
"st %%g0, %1\n\t"
"ld %1, %%fsr\n\t"
"nop; nop; nop"
: "=m" (*b), "=m" (__fsr));
}
#endif /* __sparc */
#if defined(__sparc)
extern __inline__ void
__set_ieee_flags(__ieee_flags_type *b)
{
/*
* It's preferable to let the assembler insert the nops as
* needed; however, it warns as it does so. Add them here for now.
*/
__asm__ __volatile__(
"ld %0, %%fsr\n\t"
"nop; nop; nop"
: /* no outputs */
: "m" (*b));
}
#endif /* __sparc */
#endif /* !__lint && __GNUC__ */
#endif /* _BASE_INLINES_H */