162306a36Sopenharmony_ci/* Software floating-point emulation.
262306a36Sopenharmony_ci   Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
362306a36Sopenharmony_ci   This file is part of the GNU C Library.
462306a36Sopenharmony_ci   Contributed by Richard Henderson (rth@cygnus.com),
562306a36Sopenharmony_ci		  Jakub Jelinek (jj@ultra.linux.cz),
662306a36Sopenharmony_ci		  David S. Miller (davem@redhat.com) and
762306a36Sopenharmony_ci		  Peter Maydell (pmaydell@chiark.greenend.org.uk).
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci   The GNU C Library is free software; you can redistribute it and/or
1062306a36Sopenharmony_ci   modify it under the terms of the GNU Library General Public License as
1162306a36Sopenharmony_ci   published by the Free Software Foundation; either version 2 of the
1262306a36Sopenharmony_ci   License, or (at your option) any later version.
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci   The GNU C Library is distributed in the hope that it will be useful,
1562306a36Sopenharmony_ci   but WITHOUT ANY WARRANTY; without even the implied warranty of
1662306a36Sopenharmony_ci   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1762306a36Sopenharmony_ci   Library General Public License for more details.
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci   You should have received a copy of the GNU Library General Public
2062306a36Sopenharmony_ci   License along with the GNU C Library; see the file COPYING.LIB.  If
2162306a36Sopenharmony_ci   not, write to the Free Software Foundation, Inc.,
2262306a36Sopenharmony_ci   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci#ifndef __MATH_EMU_SOFT_FP_H__
2562306a36Sopenharmony_ci#define __MATH_EMU_SOFT_FP_H__
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci#include <asm/sfp-machine.h>
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci/* Allow sfp-machine to have its own byte order definitions. */
3062306a36Sopenharmony_ci#ifndef __BYTE_ORDER
3162306a36Sopenharmony_ci#include <endian.h>
3262306a36Sopenharmony_ci#endif
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci#define _FP_WORKBITS		3
3562306a36Sopenharmony_ci#define _FP_WORK_LSB		((_FP_W_TYPE)1 << 3)
3662306a36Sopenharmony_ci#define _FP_WORK_ROUND		((_FP_W_TYPE)1 << 2)
3762306a36Sopenharmony_ci#define _FP_WORK_GUARD		((_FP_W_TYPE)1 << 1)
3862306a36Sopenharmony_ci#define _FP_WORK_STICKY		((_FP_W_TYPE)1 << 0)
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci#ifndef FP_RND_NEAREST
4162306a36Sopenharmony_ci# define FP_RND_NEAREST		0
4262306a36Sopenharmony_ci# define FP_RND_ZERO		1
4362306a36Sopenharmony_ci# define FP_RND_PINF		2
4462306a36Sopenharmony_ci# define FP_RND_MINF		3
4562306a36Sopenharmony_ci#ifndef FP_ROUNDMODE
4662306a36Sopenharmony_ci# define FP_ROUNDMODE		FP_RND_NEAREST
4762306a36Sopenharmony_ci#endif
4862306a36Sopenharmony_ci#endif
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci/* By default don't care about exceptions. */
5162306a36Sopenharmony_ci#ifndef FP_EX_INVALID
5262306a36Sopenharmony_ci#define FP_EX_INVALID		0
5362306a36Sopenharmony_ci#endif
5462306a36Sopenharmony_ci#ifndef FP_EX_INVALID_SNAN
5562306a36Sopenharmony_ci#define FP_EX_INVALID_SNAN	0
5662306a36Sopenharmony_ci#endif
5762306a36Sopenharmony_ci/* inf - inf */
5862306a36Sopenharmony_ci#ifndef FP_EX_INVALID_ISI
5962306a36Sopenharmony_ci#define FP_EX_INVALID_ISI	0
6062306a36Sopenharmony_ci#endif
6162306a36Sopenharmony_ci/* inf / inf */
6262306a36Sopenharmony_ci#ifndef FP_EX_INVALID_IDI
6362306a36Sopenharmony_ci#define FP_EX_INVALID_IDI	0
6462306a36Sopenharmony_ci#endif
6562306a36Sopenharmony_ci/* 0 / 0 */
6662306a36Sopenharmony_ci#ifndef FP_EX_INVALID_ZDZ
6762306a36Sopenharmony_ci#define FP_EX_INVALID_ZDZ	0
6862306a36Sopenharmony_ci#endif
6962306a36Sopenharmony_ci/* inf * 0 */
7062306a36Sopenharmony_ci#ifndef FP_EX_INVALID_IMZ
7162306a36Sopenharmony_ci#define FP_EX_INVALID_IMZ	0
7262306a36Sopenharmony_ci#endif
7362306a36Sopenharmony_ci#ifndef FP_EX_OVERFLOW
7462306a36Sopenharmony_ci#define FP_EX_OVERFLOW		0
7562306a36Sopenharmony_ci#endif
7662306a36Sopenharmony_ci#ifndef FP_EX_UNDERFLOW
7762306a36Sopenharmony_ci#define FP_EX_UNDERFLOW
7862306a36Sopenharmony_ci#endif
7962306a36Sopenharmony_ci#ifndef FP_EX_DIVZERO
8062306a36Sopenharmony_ci#define FP_EX_DIVZERO		0
8162306a36Sopenharmony_ci#endif
8262306a36Sopenharmony_ci#ifndef FP_EX_INEXACT
8362306a36Sopenharmony_ci#define FP_EX_INEXACT		0
8462306a36Sopenharmony_ci#endif
8562306a36Sopenharmony_ci#ifndef FP_EX_DENORM
8662306a36Sopenharmony_ci#define FP_EX_DENORM		0
8762306a36Sopenharmony_ci#endif
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci#ifdef _FP_DECL_EX
9062306a36Sopenharmony_ci#define FP_DECL_EX					\
9162306a36Sopenharmony_ci  int _fex = 0;						\
9262306a36Sopenharmony_ci  _FP_DECL_EX
9362306a36Sopenharmony_ci#else
9462306a36Sopenharmony_ci#define FP_DECL_EX int _fex = 0
9562306a36Sopenharmony_ci#endif
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci#ifndef FP_INIT_ROUNDMODE
9862306a36Sopenharmony_ci#define FP_INIT_ROUNDMODE do {} while (0)
9962306a36Sopenharmony_ci#endif
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci#ifndef FP_HANDLE_EXCEPTIONS
10262306a36Sopenharmony_ci#define FP_HANDLE_EXCEPTIONS do {} while (0)
10362306a36Sopenharmony_ci#endif
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci/* By default we never flush denormal input operands to signed zero. */
10662306a36Sopenharmony_ci#ifndef FP_DENORM_ZERO
10762306a36Sopenharmony_ci#define FP_DENORM_ZERO 0
10862306a36Sopenharmony_ci#endif
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci#ifndef FP_INHIBIT_RESULTS
11162306a36Sopenharmony_ci/* By default we write the results always.
11262306a36Sopenharmony_ci * sfp-machine may override this and e.g.
11362306a36Sopenharmony_ci * check if some exceptions are unmasked
11462306a36Sopenharmony_ci * and inhibit it in such a case.
11562306a36Sopenharmony_ci */
11662306a36Sopenharmony_ci#define FP_INHIBIT_RESULTS 0
11762306a36Sopenharmony_ci#endif
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci#ifndef FP_TRAPPING_EXCEPTIONS
12062306a36Sopenharmony_ci#define FP_TRAPPING_EXCEPTIONS 0
12162306a36Sopenharmony_ci#endif
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci#define FP_SET_EXCEPTION(ex)				\
12462306a36Sopenharmony_ci  _fex |= (ex)
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci#define FP_UNSET_EXCEPTION(ex)				\
12762306a36Sopenharmony_ci  _fex &= ~(ex)
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci#define FP_CUR_EXCEPTIONS				\
13062306a36Sopenharmony_ci  (_fex)
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ci#define FP_CLEAR_EXCEPTIONS				\
13362306a36Sopenharmony_ci  _fex = 0
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci#define _FP_ROUND_NEAREST(wc, X)			\
13662306a36Sopenharmony_cido {							\
13762306a36Sopenharmony_ci    if ((_FP_FRAC_LOW_##wc(X) & 15) != _FP_WORK_ROUND)	\
13862306a36Sopenharmony_ci      _FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND);		\
13962306a36Sopenharmony_ci} while (0)
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ci#define _FP_ROUND_ZERO(wc, X)		(void)0
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci#define _FP_ROUND_PINF(wc, X)				\
14462306a36Sopenharmony_cido {							\
14562306a36Sopenharmony_ci    if (!X##_s && (_FP_FRAC_LOW_##wc(X) & 7))		\
14662306a36Sopenharmony_ci      _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB);		\
14762306a36Sopenharmony_ci} while (0)
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci#define _FP_ROUND_MINF(wc, X)				\
15062306a36Sopenharmony_cido {							\
15162306a36Sopenharmony_ci    if (X##_s && (_FP_FRAC_LOW_##wc(X) & 7))		\
15262306a36Sopenharmony_ci      _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB);		\
15362306a36Sopenharmony_ci} while (0)
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_ci#define _FP_ROUND(wc, X)			\
15662306a36Sopenharmony_cido {						\
15762306a36Sopenharmony_ci	if (_FP_FRAC_LOW_##wc(X) & 7)		\
15862306a36Sopenharmony_ci	  FP_SET_EXCEPTION(FP_EX_INEXACT);	\
15962306a36Sopenharmony_ci	switch (FP_ROUNDMODE)			\
16062306a36Sopenharmony_ci	{					\
16162306a36Sopenharmony_ci	  case FP_RND_NEAREST:			\
16262306a36Sopenharmony_ci	    _FP_ROUND_NEAREST(wc,X);		\
16362306a36Sopenharmony_ci	    break;				\
16462306a36Sopenharmony_ci	  case FP_RND_ZERO:			\
16562306a36Sopenharmony_ci	    _FP_ROUND_ZERO(wc,X);		\
16662306a36Sopenharmony_ci	    break;				\
16762306a36Sopenharmony_ci	  case FP_RND_PINF:			\
16862306a36Sopenharmony_ci	    _FP_ROUND_PINF(wc,X);		\
16962306a36Sopenharmony_ci	    break;				\
17062306a36Sopenharmony_ci	  case FP_RND_MINF:			\
17162306a36Sopenharmony_ci	    _FP_ROUND_MINF(wc,X);		\
17262306a36Sopenharmony_ci	    break;				\
17362306a36Sopenharmony_ci	}					\
17462306a36Sopenharmony_ci} while (0)
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci#define FP_CLS_NORMAL		0
17762306a36Sopenharmony_ci#define FP_CLS_ZERO		1
17862306a36Sopenharmony_ci#define FP_CLS_INF		2
17962306a36Sopenharmony_ci#define FP_CLS_NAN		3
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci#define _FP_CLS_COMBINE(x,y)	(((x) << 2) | (y))
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci#include <math-emu/op-1.h>
18462306a36Sopenharmony_ci#include <math-emu/op-2.h>
18562306a36Sopenharmony_ci#include <math-emu/op-4.h>
18662306a36Sopenharmony_ci#include <math-emu/op-8.h>
18762306a36Sopenharmony_ci#include <math-emu/op-common.h>
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_ci/* Sigh.  Silly things longlong.h needs.  */
19062306a36Sopenharmony_ci#define UWtype		_FP_W_TYPE
19162306a36Sopenharmony_ci#define W_TYPE_SIZE	_FP_W_TYPE_SIZE
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_citypedef int SItype __attribute__((mode(SI)));
19462306a36Sopenharmony_citypedef int DItype __attribute__((mode(DI)));
19562306a36Sopenharmony_citypedef unsigned int USItype __attribute__((mode(SI)));
19662306a36Sopenharmony_citypedef unsigned int UDItype __attribute__((mode(DI)));
19762306a36Sopenharmony_ci#if _FP_W_TYPE_SIZE == 32
19862306a36Sopenharmony_citypedef unsigned int UHWtype __attribute__((mode(HI)));
19962306a36Sopenharmony_ci#elif _FP_W_TYPE_SIZE == 64
20062306a36Sopenharmony_citypedef USItype UHWtype;
20162306a36Sopenharmony_ci#endif
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_ci#ifndef umul_ppmm
20462306a36Sopenharmony_ci#include <stdlib/longlong.h>
20562306a36Sopenharmony_ci#endif
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_ci#endif /* __MATH_EMU_SOFT_FP_H__ */
208