floatingpoint.h revision 2941
1139804Simp/*-
22729Sdfr * Copyright (c) 1993 Andrew Moore, Talke Studio
32729Sdfr * All rights reserved.
42729Sdfr *
52729Sdfr * Redistribution and use in source and binary forms, with or without
62729Sdfr * modification, are permitted provided that the following conditions
72729Sdfr * are met:
82729Sdfr * 1. Redistributions of source code must retain the above copyright
92729Sdfr *    notice, this list of conditions and the following disclaimer.
102729Sdfr * 2. Redistributions in binary form must reproduce the above copyright
112729Sdfr *    notice, this list of conditions and the following disclaimer in the
122729Sdfr *    documentation and/or other materials provided with the distribution.
132729Sdfr * 3. All advertising materials mentioning features or use of this software
142729Sdfr *    must display the following acknowledgement:
152729Sdfr *	This product includes software developed by the University of
162729Sdfr *	California, Berkeley and its contributors.
172729Sdfr * 4. Neither the name of the University nor the names of its contributors
182729Sdfr *    may be used to endorse or promote products derived from this software
19140614Srwatson *    without specific prior written permission.
20140614Srwatson *
21140614Srwatson * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22140614Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23140614Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24140614Srwatson * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25140614Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26140614Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27140614Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28140614Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29140614Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30140614Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31140614Srwatson * SUCH DAMAGE.
32140614Srwatson *
33140614Srwatson *	from: @(#) floatingpoint.h	1.0 (Berkeley) 9/23/93
34140614Srwatson *	$Id: floatingpoint.h,v 1.5 1994/08/04 19:16:36 wollman Exp $
35140614Srwatson */
36140614Srwatson
37140614Srwatson#ifndef _FLOATINGPOINT_H_
38140614Srwatson#define _FLOATINGPOINT_H_
39140614Srwatson
40140614Srwatson/*
41140614Srwatson * IEEE floating point structure and function definitions
42140614Srwatson */
43140614Srwatson
44140614Srwatson/*-
45140614Srwatson * XXX the following undocumented pollution is exported:
46140614Srwatson *	fpsetsticky().
47140614Srwatson *	FP*FLD, FP*OFF and FP*REG from <machine/ieeefp.h>
48140614Srwatson */
492729Sdfr
50116182Sobrien#include <sys/cdefs.h>
51116182Sobrien#include <machine/ieeefp.h>
52116182Sobrien
5359839Speter#ifdef __GNUC__
54140614Srwatson
5559839Speter#define __fldenv(addr)	__asm __volatile("fldenv %0" : : "m" (*(addr)))
562729Sdfr#define __fnstenv(addr)	__asm __volatile("fnstenv %0" : "=m" (*(addr)))
572729Sdfr#define __fnstcw(addr)	__asm __volatile("fnstcw %0" : "=m" (*(addr)))
5811626Sbde#define __fnstsw(addr)	__asm __volatile("fnstsw %0" : "=m" (*(addr)))
592729Sdfr
602729Sdfr/*
6182607Sdillon * return the contents of a FP register
62140614Srwatson */
6382607Sdillonstatic __inline__ int
64129882Sphk__fpgetreg(int _reg)
652729Sdfr{
6669449Salfred	unsigned short _mem;
67140839Ssobomax
6811626Sbde	/*-
6959839Speter	 * This is more efficient than it looks.  The switch gets optimized
7059839Speter	 * away if _reg is constant.
7168024Srwatson	 *
722729Sdfr	 * The default case only supports _reg == 0.  We could handle more
7359839Speter	 * registers (e.g., tags) using fnstenv, but the interface doesn't
7459839Speter	 * support more.
7592723Salfred	 */
7692723Salfred	switch(_reg) {
7792723Salfred	default:
7810358Sjulian		__fnstcw(&_mem);
79100523Salfred		break;
80100523Salfred	case FP_STKY_REG:
81100523Salfred		__fnstsw(&_mem);
82100523Salfred		break;
83100523Salfred	}
84140614Srwatson	return _mem;
85140614Srwatson}
86140614Srwatson
87140614Srwatson/*
88140614Srwatson * set a FP mode; return previous mode
892729Sdfr */
9092723Salfredstatic __inline__ int
912729Sdfr__fpsetreg(int _m, int _reg, int _fld, int _off)
9211626Sbde{
9312819Sphk	unsigned _env[7];
9411626Sbde	unsigned _p;
9511626Sbde
9611626Sbde	/*
972729Sdfr	 * _reg == 0 could be handled better using fnstcw/fldcw.
9859839Speter	 */
9959839Speter	__fnstenv(_env);
10059839Speter	_p =  (_env[_reg] & _fld) >> _off;
10159839Speter	_env[_reg] = (_env[_reg] & ~_fld) | (_m << _off & _fld);
10259839Speter	__fldenv(_env);
10359839Speter	return _p;
10459839Speter}
10559839Speter
10659839Speter#endif /* __GNUC__ */
10759839Speter
10859839Speter/*
10959839Speter * SysV/386 FP control interface
11059839Speter */
11159839Speter#define fpgetround()	((__fpgetreg(FP_RND_REG) & FP_RND_FLD) >> FP_RND_OFF)
11259839Speter#define fpsetround(m)	__fpsetreg((m), FP_RND_REG, FP_RND_FLD, FP_RND_OFF)
11359839Speter#define fpgetprec()	((__fpgetreg(FP_PRC_REG) & FP_PRC_FLD) >> FP_PRC_OFF)
11459839Speter#define fpsetprec(m)	__fpsetreg((m), FP_PRC_REG, FP_PRC_FLD, FP_PRC_OFF)
11559839Speter#define fpgetmask()	((~__fpgetreg(FP_MSKS_REG) & FP_MSKS_FLD) >> FP_MSKS_OFF)
11659839Speter#define fpsetmask(m)	__fpsetreg(~(m), FP_MSKS_REG, FP_MSKS_FLD, FP_MSKS_OFF)
11759839Speter#define fpgetsticky()	((__fpgetreg(FP_STKY_REG) & FP_STKY_FLD) >> FP_STKY_OFF)
11859839Speter#define fpresetsticky(m)	__fpsetreg(0, FP_STKY_REG, (m), FP_STKY_OFF)
11959839Speter#define fpsetsticky(m)	fpresetsticky(m)
12059839Speter
12159839Speter#endif /* !_FLOATINGPOINT_H_ */
12259839Speter