xref: /linux/arch/mips/math-emu/ieee754int.h (revision f86fd32d)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * IEEE754 floating point
4  * common internal header file
5  */
6 /*
7  * MIPS floating point support
8  * Copyright (C) 1994-2000 Algorithmics Ltd.
9  */
10 #ifndef __IEEE754INT_H
11 #define __IEEE754INT_H
12 
13 #include "ieee754.h"
14 
15 #define CLPAIR(x, y)	((x)*6+(y))
16 
17 enum maddf_flags {
18 	MADDF_NEGATE_PRODUCT	= 1 << 0,
19 	MADDF_NEGATE_ADDITION	= 1 << 1,
20 };
21 
22 static inline void ieee754_clearcx(void)
23 {
24 	ieee754_csr.cx = 0;
25 }
26 
27 static inline void ieee754_setcx(const unsigned int flags)
28 {
29 	ieee754_csr.cx |= flags;
30 	ieee754_csr.sx |= flags;
31 }
32 
33 static inline int ieee754_setandtestcx(const unsigned int x)
34 {
35 	ieee754_setcx(x);
36 
37 	return ieee754_csr.mx & x;
38 }
39 
40 static inline int ieee754_class_nan(int xc)
41 {
42 	return xc >= IEEE754_CLASS_SNAN;
43 }
44 
45 #define COMPXSP \
46 	unsigned int xm; int xe; int xs __maybe_unused; int xc
47 
48 #define COMPYSP \
49 	unsigned int ym; int ye; int ys; int yc
50 
51 #define COMPZSP \
52 	unsigned int zm; int ze; int zs; int zc
53 
54 #define EXPLODESP(v, vc, vs, ve, vm)					\
55 {									\
56 	vs = SPSIGN(v);							\
57 	ve = SPBEXP(v);							\
58 	vm = SPMANT(v);							\
59 	if (ve == SP_EMAX+1+SP_EBIAS) {					\
60 		if (vm == 0)						\
61 			vc = IEEE754_CLASS_INF;				\
62 		else if (ieee754_csr.nan2008 ^ !(vm & SP_MBIT(SP_FBITS - 1))) \
63 			vc = IEEE754_CLASS_QNAN;			\
64 		else							\
65 			vc = IEEE754_CLASS_SNAN;			\
66 	} else if (ve == SP_EMIN-1+SP_EBIAS) {				\
67 		if (vm) {						\
68 			ve = SP_EMIN;					\
69 			vc = IEEE754_CLASS_DNORM;			\
70 		} else							\
71 			vc = IEEE754_CLASS_ZERO;			\
72 	} else {							\
73 		ve -= SP_EBIAS;						\
74 		vm |= SP_HIDDEN_BIT;					\
75 		vc = IEEE754_CLASS_NORM;				\
76 	}								\
77 }
78 #define EXPLODEXSP EXPLODESP(x, xc, xs, xe, xm)
79 #define EXPLODEYSP EXPLODESP(y, yc, ys, ye, ym)
80 #define EXPLODEZSP EXPLODESP(z, zc, zs, ze, zm)
81 
82 
83 #define COMPXDP \
84 	u64 xm; int xe; int xs __maybe_unused; int xc
85 
86 #define COMPYDP \
87 	u64 ym; int ye; int ys; int yc
88 
89 #define COMPZDP \
90 	u64 zm; int ze; int zs; int zc
91 
92 #define EXPLODEDP(v, vc, vs, ve, vm)					\
93 {									\
94 	vm = DPMANT(v);							\
95 	vs = DPSIGN(v);							\
96 	ve = DPBEXP(v);							\
97 	if (ve == DP_EMAX+1+DP_EBIAS) {					\
98 		if (vm == 0)						\
99 			vc = IEEE754_CLASS_INF;				\
100 		else if (ieee754_csr.nan2008 ^ !(vm & DP_MBIT(DP_FBITS - 1))) \
101 			vc = IEEE754_CLASS_QNAN;			\
102 		else							\
103 			vc = IEEE754_CLASS_SNAN;			\
104 	} else if (ve == DP_EMIN-1+DP_EBIAS) {				\
105 		if (vm) {						\
106 			ve = DP_EMIN;					\
107 			vc = IEEE754_CLASS_DNORM;			\
108 		} else							\
109 			vc = IEEE754_CLASS_ZERO;			\
110 	} else {							\
111 		ve -= DP_EBIAS;						\
112 		vm |= DP_HIDDEN_BIT;					\
113 		vc = IEEE754_CLASS_NORM;				\
114 	}								\
115 }
116 #define EXPLODEXDP EXPLODEDP(x, xc, xs, xe, xm)
117 #define EXPLODEYDP EXPLODEDP(y, yc, ys, ye, ym)
118 #define EXPLODEZDP EXPLODEDP(z, zc, zs, ze, zm)
119 
120 #define FLUSHDP(v, vc, vs, ve, vm)					\
121 	if (vc==IEEE754_CLASS_DNORM) {					\
122 		if (ieee754_csr.nod) {					\
123 			ieee754_setcx(IEEE754_INEXACT);			\
124 			vc = IEEE754_CLASS_ZERO;			\
125 			ve = DP_EMIN-1+DP_EBIAS;			\
126 			vm = 0;						\
127 			v = ieee754dp_zero(vs);				\
128 		}							\
129 	}
130 
131 #define FLUSHSP(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 = SP_EMIN-1+SP_EBIAS;			\
137 			vm = 0;						\
138 			v = ieee754sp_zero(vs);				\
139 		}							\
140 	}
141 
142 #define FLUSHXDP FLUSHDP(x, xc, xs, xe, xm)
143 #define FLUSHYDP FLUSHDP(y, yc, ys, ye, ym)
144 #define FLUSHZDP FLUSHDP(z, zc, zs, ze, zm)
145 #define FLUSHXSP FLUSHSP(x, xc, xs, xe, xm)
146 #define FLUSHYSP FLUSHSP(y, yc, ys, ye, ym)
147 #define FLUSHZSP FLUSHSP(z, zc, zs, ze, zm)
148 
149 #endif /* __IEEE754INT_H  */
150