1ea65cc9bSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
24e9561b2SMarkos Chandras /*
34e9561b2SMarkos Chandras * IEEE754 floating point arithmetic
44e9561b2SMarkos Chandras * single precision: MIN{,A}.f
54e9561b2SMarkos Chandras * MIN : Scalar Floating-Point Minimum
64e9561b2SMarkos Chandras * MINA: Scalar Floating-Point argument with Minimum Absolute Value
74e9561b2SMarkos Chandras *
84e9561b2SMarkos Chandras * MIN.S : FPR[fd] = minNum(FPR[fs],FPR[ft])
94e9561b2SMarkos Chandras * MINA.S: FPR[fd] = maxNumMag(FPR[fs],FPR[ft])
104e9561b2SMarkos Chandras *
114e9561b2SMarkos Chandras * MIPS floating point support
124e9561b2SMarkos Chandras * Copyright (C) 2015 Imagination Technologies, Ltd.
134e9561b2SMarkos Chandras * Author: Markos Chandras <markos.chandras@imgtec.com>
144e9561b2SMarkos Chandras */
154e9561b2SMarkos Chandras
164e9561b2SMarkos Chandras #include "ieee754sp.h"
174e9561b2SMarkos Chandras
ieee754sp_fmin(union ieee754sp x,union ieee754sp y)184e9561b2SMarkos Chandras union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y)
194e9561b2SMarkos Chandras {
204e9561b2SMarkos Chandras COMPXSP;
214e9561b2SMarkos Chandras COMPYSP;
224e9561b2SMarkos Chandras
234e9561b2SMarkos Chandras EXPLODEXSP;
244e9561b2SMarkos Chandras EXPLODEYSP;
254e9561b2SMarkos Chandras
264e9561b2SMarkos Chandras FLUSHXSP;
274e9561b2SMarkos Chandras FLUSHYSP;
284e9561b2SMarkos Chandras
294e9561b2SMarkos Chandras ieee754_clearcx();
304e9561b2SMarkos Chandras
314e9561b2SMarkos Chandras switch (CLPAIR(xc, yc)) {
324e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
334e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
344e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
354e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
364e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
374e9561b2SMarkos Chandras return ieee754sp_nanxcpt(y);
384e9561b2SMarkos Chandras
394e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
404e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
414e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
424e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
434e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
444e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
454e9561b2SMarkos Chandras return ieee754sp_nanxcpt(x);
464e9561b2SMarkos 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 */
614e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
624e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
634e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
644e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
654e9561b2SMarkos Chandras return x;
664e9561b2SMarkos Chandras
674e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
684e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
694e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
704e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
714e9561b2SMarkos Chandras return y;
724e9561b2SMarkos Chandras
734e9561b2SMarkos Chandras /*
744e9561b2SMarkos Chandras * Infinity and zero handling
754e9561b2SMarkos Chandras */
764e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
774e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
784e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
794e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
804e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
814e9561b2SMarkos Chandras return xs ? x : y;
824e9561b2SMarkos Chandras
834e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
844e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
854e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
864e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
874e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
884e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
894e9561b2SMarkos Chandras return ys ? y : x;
904e9561b2SMarkos Chandras
914e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
9215560a58SAleksandar Markovic return ieee754sp_zero(xs | ys);
934e9561b2SMarkos Chandras
944e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
954e9561b2SMarkos Chandras SPDNORMX;
96*c9b02990SLiangliang Huang fallthrough;
974e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
984e9561b2SMarkos Chandras SPDNORMY;
994e9561b2SMarkos Chandras break;
1004e9561b2SMarkos Chandras
1014e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
1024e9561b2SMarkos Chandras SPDNORMX;
1034e9561b2SMarkos Chandras }
1044e9561b2SMarkos Chandras
1054e9561b2SMarkos Chandras /* Finally get to do some computation */
1064e9561b2SMarkos Chandras
1074e9561b2SMarkos Chandras assert(xm & SP_HIDDEN_BIT);
1084e9561b2SMarkos Chandras assert(ym & SP_HIDDEN_BIT);
1094e9561b2SMarkos Chandras
1104e9561b2SMarkos Chandras /* Compare signs */
1114e9561b2SMarkos Chandras if (xs > ys)
1124e9561b2SMarkos Chandras return x;
1134e9561b2SMarkos Chandras else if (xs < ys)
1144e9561b2SMarkos Chandras return y;
1154e9561b2SMarkos Chandras
116aabf5cf0SAleksandar Markovic /* Signs of inputs are the same, let's compare exponents */
117aabf5cf0SAleksandar Markovic if (xs == 0) {
118aabf5cf0SAleksandar Markovic /* Inputs are both positive */
1194e9561b2SMarkos Chandras if (xe > ye)
1204e9561b2SMarkos Chandras return y;
1214e9561b2SMarkos Chandras else if (xe < ye)
1224e9561b2SMarkos Chandras return x;
123aabf5cf0SAleksandar Markovic } else {
124aabf5cf0SAleksandar Markovic /* Inputs are both negative */
125aabf5cf0SAleksandar Markovic if (xe > ye)
126aabf5cf0SAleksandar Markovic return x;
127aabf5cf0SAleksandar Markovic else if (xe < ye)
128aabf5cf0SAleksandar Markovic return y;
129aabf5cf0SAleksandar Markovic }
1304e9561b2SMarkos 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 */
1344e9561b2SMarkos Chandras if (xm <= ym)
1354e9561b2SMarkos Chandras return x;
1364e9561b2SMarkos Chandras return y;
1374e9561b2SMarkos Chandras }
138aabf5cf0SAleksandar Markovic /* Inputs are both negative, with equal signs and exponents */
139aabf5cf0SAleksandar Markovic if (xm <= ym)
140aabf5cf0SAleksandar Markovic return y;
141aabf5cf0SAleksandar Markovic return x;
142aabf5cf0SAleksandar Markovic }
1434e9561b2SMarkos Chandras
ieee754sp_fmina(union ieee754sp x,union ieee754sp y)1444e9561b2SMarkos Chandras union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y)
1454e9561b2SMarkos Chandras {
1464e9561b2SMarkos Chandras COMPXSP;
1474e9561b2SMarkos Chandras COMPYSP;
1484e9561b2SMarkos Chandras
1494e9561b2SMarkos Chandras EXPLODEXSP;
1504e9561b2SMarkos Chandras EXPLODEYSP;
1514e9561b2SMarkos Chandras
1524e9561b2SMarkos Chandras FLUSHXSP;
1534e9561b2SMarkos Chandras FLUSHYSP;
1544e9561b2SMarkos Chandras
1554e9561b2SMarkos Chandras ieee754_clearcx();
1564e9561b2SMarkos Chandras
1574e9561b2SMarkos Chandras switch (CLPAIR(xc, yc)) {
1584e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
1594e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
1604e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
1614e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
1624e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
1634e9561b2SMarkos Chandras return ieee754sp_nanxcpt(y);
1644e9561b2SMarkos Chandras
1654e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
1664e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
1674e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
1684e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
1694e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
1704e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
1714e9561b2SMarkos Chandras return ieee754sp_nanxcpt(x);
1724e9561b2SMarkos 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 */
1874e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
1884e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
1894e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
1904e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
1914e9561b2SMarkos Chandras return x;
1924e9561b2SMarkos Chandras
1934e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
1944e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
1954e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
1964e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
1974e9561b2SMarkos Chandras return y;
1984e9561b2SMarkos Chandras
1994e9561b2SMarkos Chandras /*
2004e9561b2SMarkos Chandras * Infinity and zero handling
2014e9561b2SMarkos Chandras */
2023444c4ebSAleksandar Markovic case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
2033444c4ebSAleksandar Markovic return ieee754sp_inf(xs | ys);
2043444c4ebSAleksandar Markovic
2054e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
2064e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
2074e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
2084e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
2094e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
210304bfe47SAleksandar Markovic return y;
2114e9561b2SMarkos Chandras
2124e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
2134e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
2144e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
2154e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
2164e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
217304bfe47SAleksandar Markovic return x;
2184e9561b2SMarkos Chandras
2194e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
22015560a58SAleksandar Markovic return ieee754sp_zero(xs | ys);
2214e9561b2SMarkos Chandras
2224e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
2234e9561b2SMarkos Chandras SPDNORMX;
224*c9b02990SLiangliang Huang fallthrough;
2254e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
2264e9561b2SMarkos Chandras SPDNORMY;
2274e9561b2SMarkos Chandras break;
2284e9561b2SMarkos Chandras
2294e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
2304e9561b2SMarkos Chandras SPDNORMX;
2314e9561b2SMarkos Chandras }
2324e9561b2SMarkos Chandras
2334e9561b2SMarkos Chandras /* Finally get to do some computation */
2344e9561b2SMarkos Chandras
2354e9561b2SMarkos Chandras assert(xm & SP_HIDDEN_BIT);
2364e9561b2SMarkos Chandras assert(ym & SP_HIDDEN_BIT);
2374e9561b2SMarkos Chandras
2384e9561b2SMarkos Chandras /* Compare exponent */
2394e9561b2SMarkos Chandras if (xe > ye)
2404e9561b2SMarkos Chandras return y;
2414e9561b2SMarkos Chandras else if (xe < ye)
2424e9561b2SMarkos Chandras return x;
2434e9561b2SMarkos Chandras
2444e9561b2SMarkos Chandras /* Compare mantissa */
2451a41b3b4SAleksandar Markovic if (xm < ym)
2461a41b3b4SAleksandar Markovic return x;
2471a41b3b4SAleksandar Markovic else if (xm > ym)
2481a41b3b4SAleksandar Markovic return y;
2491a41b3b4SAleksandar Markovic else if (xs == 1)
2504e9561b2SMarkos Chandras return x;
2514e9561b2SMarkos Chandras return y;
2524e9561b2SMarkos Chandras }
253