WIP FPC-III support
[linux/fpc-iii.git] / arch / mips / math-emu / sp_fmax.c
blob3fb16a1df3b8d9c725b8a1c6e7176780910adef9
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
8 * MAX.S : FPR[fd] = maxNum(FPR[fs],FPR[ft])
9 * MAXA.S: FPR[fd] = maxNumMag(FPR[fs],FPR[ft])
11 * MIPS floating point support
12 * Copyright (C) 2015 Imagination Technologies, Ltd.
13 * Author: Markos Chandras <markos.chandras@imgtec.com>
16 #include "ieee754sp.h"
18 union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y)
20 COMPXSP;
21 COMPYSP;
23 EXPLODEXSP;
24 EXPLODEYSP;
26 FLUSHXSP;
27 FLUSHYSP;
29 ieee754_clearcx();
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);
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);
48 * Quiet NaN handling
52 * The case of both inputs quiet NaNs
54 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
55 return x;
58 * The cases of exactly one input quiet NaN (numbers
59 * are here preferred as returned values to NaNs)
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;
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;
74 * Infinity and zero handling
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;
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;
91 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
92 return ieee754sp_zero(xs & ys);
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;
101 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
102 SPDNORMX;
105 /* Finally get to do some computation */
107 assert(xm & SP_HIDDEN_BIT);
108 assert(ym & SP_HIDDEN_BIT);
110 /* Compare signs */
111 if (xs > ys)
112 return y;
113 else if (xs < ys)
114 return x;
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;
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;
138 /* Inputs are both negative, with equal signs and exponents */
139 if (xm <= ym)
140 return x;
141 return y;
144 union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y)
146 COMPXSP;
147 COMPYSP;
149 EXPLODEXSP;
150 EXPLODEYSP;
152 FLUSHXSP;
153 FLUSHYSP;
155 ieee754_clearcx();
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);
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);
174 * Quiet NaN handling
178 * The case of both inputs quiet NaNs
180 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
181 return x;
184 * The cases of exactly one input quiet NaN (numbers
185 * are here preferred as returned values to NaNs)
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;
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;
200 * Infinity and zero handling
202 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
203 return ieee754sp_inf(xs & ys);
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;
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;
219 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
220 return ieee754sp_zero(xs & ys);
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;
229 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
230 SPDNORMX;
233 /* Finally get to do some computation */
235 assert(xm & SP_HIDDEN_BIT);
236 assert(ym & SP_HIDDEN_BIT);
238 /* Compare exponent */
239 if (xe > ye)
240 return x;
241 else if (xe < ye)
242 return y;
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;