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