xref: /linux/include/math-emu/soft-fp.h (revision b74843b38da8f1186fd7d447646c835b47096a15)
1 /* Software floating-point emulation.
2    Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Richard Henderson (rth@cygnus.com),
5 		  Jakub Jelinek (jj@ultra.linux.cz),
6 		  David S. Miller (davem@redhat.com) and
7 		  Peter Maydell (pmaydell@chiark.greenend.org.uk).
8 
9    The GNU C Library is free software; you can redistribute it and/or
10    modify it under the terms of the GNU Library General Public License as
11    published by the Free Software Foundation; either version 2 of the
12    License, or (at your option) any later version.
13 
14    The GNU C Library is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17    Library General Public License for more details.
18 
19    You should have received a copy of the GNU Library General Public
20    License along with the GNU C Library; see the file COPYING.LIB.  If
21    not, write to the Free Software Foundation, Inc.,
22    59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
23 
24 #ifndef __MATH_EMU_SOFT_FP_H__
25 #define __MATH_EMU_SOFT_FP_H__
26 
27 #include <asm/sfp-machine.h>
28 
29 /* Allow sfp-machine to have its own byte order definitions. */
30 #ifndef __BYTE_ORDER
31 #include <endian.h>
32 #endif
33 
34 /* Whether the architecture determines tininess of a floating-point
35    result after rounding rather than before it.  IEEE 754 permits either
36    but requires the same choice for every operation, so this has to agree
37    with what the hardware does for the results it produces itself.  */
38 #ifndef _FP_TININESS_AFTER_ROUNDING
39 #define _FP_TININESS_AFTER_ROUNDING	0
40 #endif
41 
42 #define _FP_WORKBITS		3
43 #define _FP_WORK_LSB		((_FP_W_TYPE)1 << 3)
44 #define _FP_WORK_ROUND		((_FP_W_TYPE)1 << 2)
45 #define _FP_WORK_GUARD		((_FP_W_TYPE)1 << 1)
46 #define _FP_WORK_STICKY		((_FP_W_TYPE)1 << 0)
47 
48 #ifndef FP_RND_NEAREST
49 # define FP_RND_NEAREST		0
50 # define FP_RND_ZERO		1
51 # define FP_RND_PINF		2
52 # define FP_RND_MINF		3
53 #ifndef FP_ROUNDMODE
54 # define FP_ROUNDMODE		FP_RND_NEAREST
55 #endif
56 #endif
57 
58 /* By default don't care about exceptions. */
59 #ifndef FP_EX_INVALID
60 #define FP_EX_INVALID		0
61 #endif
62 #ifndef FP_EX_INVALID_SNAN
63 #define FP_EX_INVALID_SNAN	0
64 #endif
65 /* inf - inf */
66 #ifndef FP_EX_INVALID_ISI
67 #define FP_EX_INVALID_ISI	0
68 #endif
69 /* inf / inf */
70 #ifndef FP_EX_INVALID_IDI
71 #define FP_EX_INVALID_IDI	0
72 #endif
73 /* 0 / 0 */
74 #ifndef FP_EX_INVALID_ZDZ
75 #define FP_EX_INVALID_ZDZ	0
76 #endif
77 /* inf * 0 */
78 #ifndef FP_EX_INVALID_IMZ
79 #define FP_EX_INVALID_IMZ	0
80 #endif
81 #ifndef FP_EX_OVERFLOW
82 #define FP_EX_OVERFLOW		0
83 #endif
84 #ifndef FP_EX_UNDERFLOW
85 #define FP_EX_UNDERFLOW
86 #endif
87 #ifndef FP_EX_DIVZERO
88 #define FP_EX_DIVZERO		0
89 #endif
90 #ifndef FP_EX_INEXACT
91 #define FP_EX_INEXACT		0
92 #endif
93 #ifndef FP_EX_DENORM
94 #define FP_EX_DENORM		0
95 #endif
96 
97 #ifdef _FP_DECL_EX
98 #define FP_DECL_EX					\
99   int _fex = 0;						\
100   _FP_DECL_EX
101 #else
102 #define FP_DECL_EX int _fex = 0
103 #endif
104 
105 #ifndef FP_INIT_ROUNDMODE
106 #define FP_INIT_ROUNDMODE do {} while (0)
107 #endif
108 
109 #ifndef FP_HANDLE_EXCEPTIONS
110 #define FP_HANDLE_EXCEPTIONS do {} while (0)
111 #endif
112 
113 /* By default we never flush denormal input operands to signed zero. */
114 #ifndef FP_DENORM_ZERO
115 #define FP_DENORM_ZERO 0
116 #endif
117 
118 #ifndef FP_INHIBIT_RESULTS
119 /* By default we write the results always.
120  * sfp-machine may override this and e.g.
121  * check if some exceptions are unmasked
122  * and inhibit it in such a case.
123  */
124 #define FP_INHIBIT_RESULTS 0
125 #endif
126 
127 #ifndef FP_TRAPPING_EXCEPTIONS
128 #define FP_TRAPPING_EXCEPTIONS 0
129 #endif
130 
131 #define FP_SET_EXCEPTION(ex)				\
132   _fex |= (ex)
133 
134 #define FP_UNSET_EXCEPTION(ex)				\
135   _fex &= ~(ex)
136 
137 #define FP_CUR_EXCEPTIONS				\
138   (_fex)
139 
140 #define FP_CLEAR_EXCEPTIONS				\
141   _fex = 0
142 
143 #define _FP_ROUND_NEAREST(wc, X)			\
144 do {							\
145     if ((_FP_FRAC_LOW_##wc(X) & 15) != _FP_WORK_ROUND)	\
146       _FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND);		\
147 } while (0)
148 
149 #define _FP_ROUND_ZERO(wc, X)		(void)0
150 
151 #define _FP_ROUND_PINF(wc, X)				\
152 do {							\
153     if (!X##_s && (_FP_FRAC_LOW_##wc(X) & 7))		\
154       _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB);		\
155 } while (0)
156 
157 #define _FP_ROUND_MINF(wc, X)				\
158 do {							\
159     if (X##_s && (_FP_FRAC_LOW_##wc(X) & 7))		\
160       _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB);		\
161 } while (0)
162 
163 #define _FP_ROUND(wc, X)			\
164 do {						\
165 	if (_FP_FRAC_LOW_##wc(X) & 7)		\
166 	  FP_SET_EXCEPTION(FP_EX_INEXACT);	\
167 	switch (FP_ROUNDMODE)			\
168 	{					\
169 	  case FP_RND_NEAREST:			\
170 	    _FP_ROUND_NEAREST(wc,X);		\
171 	    break;				\
172 	  case FP_RND_ZERO:			\
173 	    _FP_ROUND_ZERO(wc,X);		\
174 	    break;				\
175 	  case FP_RND_PINF:			\
176 	    _FP_ROUND_PINF(wc,X);		\
177 	    break;				\
178 	  case FP_RND_MINF:			\
179 	    _FP_ROUND_MINF(wc,X);		\
180 	    break;				\
181 	}					\
182 } while (0)
183 
184 #define FP_CLS_NORMAL		0
185 #define FP_CLS_ZERO		1
186 #define FP_CLS_INF		2
187 #define FP_CLS_NAN		3
188 
189 #define _FP_CLS_COMBINE(x,y)	(((x) << 2) | (y))
190 
191 #include <math-emu/op-1.h>
192 #include <math-emu/op-2.h>
193 #include <math-emu/op-4.h>
194 #include <math-emu/op-8.h>
195 #include <math-emu/op-common.h>
196 
197 /* Sigh.  Silly things longlong.h needs.  */
198 #define UWtype		_FP_W_TYPE
199 #define W_TYPE_SIZE	_FP_W_TYPE_SIZE
200 
201 typedef int SItype __attribute__((mode(SI)));
202 typedef int DItype __attribute__((mode(DI)));
203 typedef unsigned int USItype __attribute__((mode(SI)));
204 typedef unsigned int UDItype __attribute__((mode(DI)));
205 #if _FP_W_TYPE_SIZE == 32
206 typedef unsigned int UHWtype __attribute__((mode(HI)));
207 #elif _FP_W_TYPE_SIZE == 64
208 typedef USItype UHWtype;
209 #endif
210 
211 #ifndef umul_ppmm
212 #include <stdlib/longlong.h>
213 #endif
214 
215 #endif /* __MATH_EMU_SOFT_FP_H__ */
216