diff options
Diffstat (limited to 'arch/mips/math-emu/sp_fmax.c')
-rw-r--r-- | arch/mips/math-emu/sp_fmax.c | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/arch/mips/math-emu/sp_fmax.c b/arch/mips/math-emu/sp_fmax.c new file mode 100644 index 000000000..3fb16a1df --- /dev/null +++ b/arch/mips/math-emu/sp_fmax.c | |||
@@ -0,0 +1,252 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
2 | /* | ||
3 | * IEEE754 floating point arithmetic | ||
4 | * single precision: MAX{,A}.f | ||
5 | * MAX : Scalar Floating-Point Maximum | ||
6 | * MAXA: Scalar Floating-Point argument with Maximum Absolute Value | ||
7 | * | ||
8 | * MAX.S : FPR[fd] = maxNum(FPR[fs],FPR[ft]) | ||
9 | * MAXA.S: FPR[fd] = maxNumMag(FPR[fs],FPR[ft]) | ||
10 | * | ||
11 | * MIPS floating point support | ||
12 | * Copyright (C) 2015 Imagination Technologies, Ltd. | ||
13 | * Author: Markos Chandras <markos.chandras@imgtec.com> | ||
14 | */ | ||
15 | |||
16 | #include "ieee754sp.h" | ||
17 | |||
18 | union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y) | ||
19 | { | ||
20 | COMPXSP; | ||
21 | COMPYSP; | ||
22 | |||
23 | EXPLODEXSP; | ||
24 | EXPLODEYSP; | ||
25 | |||
26 | FLUSHXSP; | ||
27 | FLUSHYSP; | ||
28 | |||
29 | ieee754_clearcx(); | ||
30 | |||
31 | switch (CLPAIR(xc, yc)) { | ||
32 | case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): | ||
33 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): | ||
34 | case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): | ||
35 | case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): | ||
36 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): | ||
37 | return ieee754sp_nanxcpt(y); | ||
38 | |||
39 | case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): | ||
40 | case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): | ||
41 | case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): | ||
42 | case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): | ||
43 | case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): | ||
44 | case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): | ||
45 | return ieee754sp_nanxcpt(x); | ||
46 | |||
47 | /* | ||
48 | * Quiet NaN handling | ||
49 | */ | ||
50 | |||
51 | /* | ||
52 | * The case of both inputs quiet NaNs | ||
53 | */ | ||
54 | case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): | ||
55 | return x; | ||
56 | |||
57 | /* | ||
58 | * The cases of exactly one input quiet NaN (numbers | ||
59 | * are here preferred as returned values to NaNs) | ||
60 | */ | ||
61 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): | ||
62 | case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): | ||
63 | case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): | ||
64 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): | ||
65 | return x; | ||
66 | |||
67 | case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): | ||
68 | case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): | ||
69 | case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): | ||
70 | case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): | ||
71 | return y; | ||
72 | |||
73 | /* | ||
74 | * Infinity and zero handling | ||
75 | */ | ||
76 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): | ||
77 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): | ||
78 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): | ||
79 | case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): | ||
80 | case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): | ||
81 | return xs ? y : x; | ||
82 | |||
83 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): | ||
84 | case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): | ||
85 | case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): | ||
86 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): | ||
87 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): | ||
88 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): | ||
89 | return ys ? x : y; | ||
90 | |||
91 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): | ||
92 | return ieee754sp_zero(xs & ys); | ||
93 | |||
94 | case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): | ||
95 | SPDNORMX; | ||
96 | fallthrough; | ||
97 | case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): | ||
98 | SPDNORMY; | ||
99 | break; | ||
100 | |||
101 | case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): | ||
102 | SPDNORMX; | ||
103 | } | ||
104 | |||
105 | /* Finally get to do some computation */ | ||
106 | |||
107 | assert(xm & SP_HIDDEN_BIT); | ||
108 | assert(ym & SP_HIDDEN_BIT); | ||
109 | |||
110 | /* Compare signs */ | ||
111 | if (xs > ys) | ||
112 | return y; | ||
113 | else if (xs < ys) | ||
114 | return x; | ||
115 | |||
116 | /* Signs of inputs are equal, let's compare exponents */ | ||
117 | if (xs == 0) { | ||
118 | /* Inputs are both positive */ | ||
119 | if (xe > ye) | ||
120 | return x; | ||
121 | else if (xe < ye) | ||
122 | return y; | ||
123 | } else { | ||
124 | /* Inputs are both negative */ | ||
125 | if (xe > ye) | ||
126 | return y; | ||
127 | else if (xe < ye) | ||
128 | return x; | ||
129 | } | ||
130 | |||
131 | /* Signs and exponents of inputs are equal, let's compare mantissas */ | ||
132 | if (xs == 0) { | ||
133 | /* Inputs are both positive, with equal signs and exponents */ | ||
134 | if (xm <= ym) | ||
135 | return y; | ||
136 | return x; | ||
137 | } | ||
138 | /* Inputs are both negative, with equal signs and exponents */ | ||
139 | if (xm <= ym) | ||
140 | return x; | ||
141 | return y; | ||
142 | } | ||
143 | |||
144 | union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y) | ||
145 | { | ||
146 | COMPXSP; | ||
147 | COMPYSP; | ||
148 | |||
149 | EXPLODEXSP; | ||
150 | EXPLODEYSP; | ||
151 | |||
152 | FLUSHXSP; | ||
153 | FLUSHYSP; | ||
154 | |||
155 | ieee754_clearcx(); | ||
156 | |||
157 | switch (CLPAIR(xc, yc)) { | ||
158 | case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): | ||
159 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): | ||
160 | case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): | ||
161 | case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): | ||
162 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): | ||
163 | return ieee754sp_nanxcpt(y); | ||
164 | |||
165 | case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): | ||
166 | case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): | ||
167 | case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): | ||
168 | case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): | ||
169 | case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): | ||
170 | case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): | ||
171 | return ieee754sp_nanxcpt(x); | ||
172 | |||
173 | /* | ||
174 | * Quiet NaN handling | ||
175 | */ | ||
176 | |||
177 | /* | ||
178 | * The case of both inputs quiet NaNs | ||
179 | */ | ||
180 | case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): | ||
181 | return x; | ||
182 | |||
183 | /* | ||
184 | * The cases of exactly one input quiet NaN (numbers | ||
185 | * are here preferred as returned values to NaNs) | ||
186 | */ | ||
187 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): | ||
188 | case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): | ||
189 | case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): | ||
190 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): | ||
191 | return x; | ||
192 | |||
193 | case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): | ||
194 | case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): | ||
195 | case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): | ||
196 | case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): | ||
197 | return y; | ||
198 | |||
199 | /* | ||
200 | * Infinity and zero handling | ||
201 | */ | ||
202 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): | ||
203 | return ieee754sp_inf(xs & ys); | ||
204 | |||
205 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): | ||
206 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): | ||
207 | case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): | ||
208 | case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): | ||
209 | case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): | ||
210 | return x; | ||
211 | |||
212 | case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): | ||
213 | case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): | ||
214 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): | ||
215 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): | ||
216 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): | ||
217 | return y; | ||
218 | |||
219 | case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): | ||
220 | return ieee754sp_zero(xs & ys); | ||
221 | |||
222 | case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): | ||
223 | SPDNORMX; | ||
224 | fallthrough; | ||
225 | case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): | ||
226 | SPDNORMY; | ||
227 | break; | ||
228 | |||
229 | case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): | ||
230 | SPDNORMX; | ||
231 | } | ||
232 | |||
233 | /* Finally get to do some computation */ | ||
234 | |||
235 | assert(xm & SP_HIDDEN_BIT); | ||
236 | assert(ym & SP_HIDDEN_BIT); | ||
237 | |||
238 | /* Compare exponent */ | ||
239 | if (xe > ye) | ||
240 | return x; | ||
241 | else if (xe < ye) | ||
242 | return y; | ||
243 | |||
244 | /* Compare mantissa */ | ||
245 | if (xm < ym) | ||
246 | return y; | ||
247 | else if (xm > ym) | ||
248 | return x; | ||
249 | else if (xs == 0) | ||
250 | return x; | ||
251 | return y; | ||
252 | } | ||