1/*-
  2 * SPDX-License-Identifier: BSD-4-Clause
  3 *
  4 * Copyright (c) 2003 Peter Wemm.
  5 * Copyright (c) 1990 Andrew Moore, Talke Studio
  6 * All rights reserved.
  7 *
  8 * Redistribution and use in source and binary forms, with or without
  9 * modification, are permitted provided that the following conditions
 10 * are met:
 11 * 1. Redistributions of source code must retain the above copyright
 12 *    notice, this list of conditions and the following disclaimer.
 13 * 2. Redistributions in binary form must reproduce the above copyright
 14 *    notice, this list of conditions and the following disclaimer in the
 15 *    documentation and/or other materials provided with the distribution.
 16 * 3. All advertising materials mentioning features or use of this software
 17 *    must display the following acknowledgement:
 18 *	This product includes software developed by the University of
 19 *	California, Berkeley and its contributors.
 20 * 4. Neither the name of the University nor the names of its contributors
 21 *    may be used to endorse or promote products derived from this software
 22 *    without specific prior written permission.
 23 *
 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 27 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 34 * SUCH DAMAGE.
 35 *
 36 * 	from: @(#) ieeefp.h 	1.0 (Berkeley) 9/23/93
 37 */
 38
 39#ifndef _MACHINE_IEEEFP_H_
 40#define _MACHINE_IEEEFP_H_
 41
 42/* Deprecated historical FPU control interface */
 43
 44#include <x86/x86_ieeefp.h>
 45
 46static __inline fp_rnd_t
 47fpgetround(void)
 48{
 49	unsigned short _cw;
 50
 51	__fnstcw(&_cw);
 52	return ((fp_rnd_t)((_cw & FP_RND_FLD) >> FP_RND_OFF));
 53}
 54
 55static __inline fp_rnd_t
 56fpsetround(fp_rnd_t _m)
 57{
 58	fp_rnd_t _p;
 59	unsigned short _cw, _newcw;
 60
 61	__fnstcw(&_cw);
 62	_p = (fp_rnd_t)((_cw & FP_RND_FLD) >> FP_RND_OFF);
 63	_newcw = _cw & ~FP_RND_FLD;
 64	_newcw |= (_m << FP_RND_OFF) & FP_RND_FLD;
 65	__fnldcw(_cw, _newcw);
 66	return (_p);
 67}
 68
 69static __inline fp_prec_t
 70fpgetprec(void)
 71{
 72	unsigned short _cw;
 73
 74	__fnstcw(&_cw);
 75	return ((fp_prec_t)((_cw & FP_PRC_FLD) >> FP_PRC_OFF));
 76}
 77
 78static __inline fp_prec_t
 79fpsetprec(fp_prec_t _m)
 80{
 81	fp_prec_t _p;
 82	unsigned short _cw, _newcw;
 83
 84	__fnstcw(&_cw);
 85	_p = (fp_prec_t)((_cw & FP_PRC_FLD) >> FP_PRC_OFF);
 86	_newcw = _cw & ~FP_PRC_FLD;
 87	_newcw |= (_m << FP_PRC_OFF) & FP_PRC_FLD;
 88	__fnldcw(_cw, _newcw);
 89	return (_p);
 90}
 91
 92/*
 93 * Get or set the exception mask.
 94 * Note that the x87 mask bits are inverted by the API -- a mask bit of 1
 95 * means disable for x87 and SSE, but for fp*mask() it means enable.
 96 */
 97
 98static __inline fp_except_t
 99fpgetmask(void)
100{
101	unsigned short _cw;
102
103	__fnstcw(&_cw);
104	return ((~_cw & FP_MSKS_FLD) >> FP_MSKS_OFF);
105}
106
107static __inline fp_except_t
108fpsetmask(fp_except_t _m)
109{
110	fp_except_t _p;
111	unsigned short _cw, _newcw;
112
113	__fnstcw(&_cw);
114	_p = (~_cw & FP_MSKS_FLD) >> FP_MSKS_OFF;
115	_newcw = _cw & ~FP_MSKS_FLD;
116	_newcw |= (~_m << FP_MSKS_OFF) & FP_MSKS_FLD;
117	__fnldcw(_cw, _newcw);
118	return (_p);
119}
120
121static __inline fp_except_t
122fpgetsticky(void)
123{
124	unsigned _ex;
125	unsigned short _sw;
126
127	__fnstsw(&_sw);
128	_ex = (_sw & FP_STKY_FLD) >> FP_STKY_OFF;
129	return ((fp_except_t)_ex);
130}
131
132static __inline fp_except_t
133fpresetsticky(fp_except_t _m)
134{
135	struct {
136		unsigned _cw;
137		unsigned _sw;
138		unsigned _other[5];
139	} _env;
140	fp_except_t _p;
141
142	_m &= FP_STKY_FLD >> FP_STKY_OFF;
143	_p = fpgetsticky();
144	if ((_p & ~_m) == _p)
145		return (_p);
146	if ((_p & ~_m) == 0) {
147		__fnclex();
148		return (_p);
149	}
150	__fnstenv(&_env);
151	_env._sw &= ~_m;
152	__fldenv(&_env);
153	return (_p);
154}
155
156#endif /* !_MACHINE_IEEEFP_H_ */