xref: /linux/arch/mips/math-emu/ieee754int.h (revision e9f0878c4b2004ac19581274c1ae4c61ae3ca70e)
1 /*
2  * IEEE754 floating point
3  * common internal header file
4  */
5 /*
6  * MIPS floating point support
7  * Copyright (C) 1994-2000 Algorithmics Ltd.
8  *
9  *  This program is free software; you can distribute it and/or modify it
10  *  under the terms of the GNU General Public License (Version 2) as
11  *  published by the Free Software Foundation.
12  *
13  *  This program is distributed in the hope it will be useful, but WITHOUT
14  *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16  *  for more details.
17  *
18  *  You should have received a copy of the GNU General Public License along
19  *  with this program; if not, write to the Free Software Foundation, Inc.,
20  *  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
21  */
22 #ifndef __IEEE754INT_H
23 #define __IEEE754INT_H
24 
25 #include "ieee754.h"
26 
27 #define CLPAIR(x, y)	((x)*6+(y))
28 
29 enum maddf_flags {
30 	MADDF_NEGATE_PRODUCT	= 1 << 0,
31 };
32 
33 static inline void ieee754_clearcx(void)
34 {
35 	ieee754_csr.cx = 0;
36 }
37 
38 static inline void ieee754_setcx(const unsigned int flags)
39 {
40 	ieee754_csr.cx |= flags;
41 	ieee754_csr.sx |= flags;
42 }
43 
44 static inline int ieee754_setandtestcx(const unsigned int x)
45 {
46 	ieee754_setcx(x);
47 
48 	return ieee754_csr.mx & x;
49 }
50 
51 static inline int ieee754_class_nan(int xc)
52 {
53 	return xc >= IEEE754_CLASS_SNAN;
54 }
55 
56 #define COMPXSP \
57 	unsigned int xm; int xe; int xs __maybe_unused; int xc
58 
59 #define COMPYSP \
60 	unsigned int ym; int ye; int ys; int yc
61 
62 #define COMPZSP \
63 	unsigned int zm; int ze; int zs; int zc
64 
65 #define EXPLODESP(v, vc, vs, ve, vm)					\
66 {									\
67 	vs = SPSIGN(v);							\
68 	ve = SPBEXP(v);							\
69 	vm = SPMANT(v);							\
70 	if (ve == SP_EMAX+1+SP_EBIAS) {					\
71 		if (vm == 0)						\
72 			vc = IEEE754_CLASS_INF;				\
73 		else if (ieee754_csr.nan2008 ^ !(vm & SP_MBIT(SP_FBITS - 1))) \
74 			vc = IEEE754_CLASS_QNAN;			\
75 		else							\
76 			vc = IEEE754_CLASS_SNAN;			\
77 	} else if (ve == SP_EMIN-1+SP_EBIAS) {				\
78 		if (vm) {						\
79 			ve = SP_EMIN;					\
80 			vc = IEEE754_CLASS_DNORM;			\
81 		} else							\
82 			vc = IEEE754_CLASS_ZERO;			\
83 	} else {							\
84 		ve -= SP_EBIAS;						\
85 		vm |= SP_HIDDEN_BIT;					\
86 		vc = IEEE754_CLASS_NORM;				\
87 	}								\
88 }
89 #define EXPLODEXSP EXPLODESP(x, xc, xs, xe, xm)
90 #define EXPLODEYSP EXPLODESP(y, yc, ys, ye, ym)
91 #define EXPLODEZSP EXPLODESP(z, zc, zs, ze, zm)
92 
93 
94 #define COMPXDP \
95 	u64 xm; int xe; int xs __maybe_unused; int xc
96 
97 #define COMPYDP \
98 	u64 ym; int ye; int ys; int yc
99 
100 #define COMPZDP \
101 	u64 zm; int ze; int zs; int zc
102 
103 #define EXPLODEDP(v, vc, vs, ve, vm)					\
104 {									\
105 	vm = DPMANT(v);							\
106 	vs = DPSIGN(v);							\
107 	ve = DPBEXP(v);							\
108 	if (ve == DP_EMAX+1+DP_EBIAS) {					\
109 		if (vm == 0)						\
110 			vc = IEEE754_CLASS_INF;				\
111 		else if (ieee754_csr.nan2008 ^ !(vm & DP_MBIT(DP_FBITS - 1))) \
112 			vc = IEEE754_CLASS_QNAN;			\
113 		else							\
114 			vc = IEEE754_CLASS_SNAN;			\
115 	} else if (ve == DP_EMIN-1+DP_EBIAS) {				\
116 		if (vm) {						\
117 			ve = DP_EMIN;					\
118 			vc = IEEE754_CLASS_DNORM;			\
119 		} else							\
120 			vc = IEEE754_CLASS_ZERO;			\
121 	} else {							\
122 		ve -= DP_EBIAS;						\
123 		vm |= DP_HIDDEN_BIT;					\
124 		vc = IEEE754_CLASS_NORM;				\
125 	}								\
126 }
127 #define EXPLODEXDP EXPLODEDP(x, xc, xs, xe, xm)
128 #define EXPLODEYDP EXPLODEDP(y, yc, ys, ye, ym)
129 #define EXPLODEZDP EXPLODEDP(z, zc, zs, ze, zm)
130 
131 #define FLUSHDP(v, vc, vs, ve, vm)					\
132 	if (vc==IEEE754_CLASS_DNORM) {					\
133 		if (ieee754_csr.nod) {					\
134 			ieee754_setcx(IEEE754_INEXACT);			\
135 			vc = IEEE754_CLASS_ZERO;			\
136 			ve = DP_EMIN-1+DP_EBIAS;			\
137 			vm = 0;						\
138 			v = ieee754dp_zero(vs);				\
139 		}							\
140 	}
141 
142 #define FLUSHSP(v, vc, vs, ve, vm)					\
143 	if (vc==IEEE754_CLASS_DNORM) {					\
144 		if (ieee754_csr.nod) {					\
145 			ieee754_setcx(IEEE754_INEXACT);			\
146 			vc = IEEE754_CLASS_ZERO;			\
147 			ve = SP_EMIN-1+SP_EBIAS;			\
148 			vm = 0;						\
149 			v = ieee754sp_zero(vs);				\
150 		}							\
151 	}
152 
153 #define FLUSHXDP FLUSHDP(x, xc, xs, xe, xm)
154 #define FLUSHYDP FLUSHDP(y, yc, ys, ye, ym)
155 #define FLUSHZDP FLUSHDP(z, zc, zs, ze, zm)
156 #define FLUSHXSP FLUSHSP(x, xc, xs, xe, xm)
157 #define FLUSHYSP FLUSHSP(y, yc, ys, ye, ym)
158 #define FLUSHZSP FLUSHSP(z, zc, zs, ze, zm)
159 
160 #endif /* __IEEE754INT_H  */
161