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 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 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