1*ea65cc9bSThomas 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; 962a14b21aSAleksandar Markovic /* fall through */ 974e9561b2SMarkos Chandras 984e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): 994e9561b2SMarkos Chandras SPDNORMY; 1004e9561b2SMarkos Chandras break; 1014e9561b2SMarkos Chandras 1024e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): 1034e9561b2SMarkos Chandras SPDNORMX; 1044e9561b2SMarkos Chandras } 1054e9561b2SMarkos Chandras 1064e9561b2SMarkos Chandras /* Finally get to do some computation */ 1074e9561b2SMarkos Chandras 1084e9561b2SMarkos Chandras assert(xm & SP_HIDDEN_BIT); 1094e9561b2SMarkos Chandras assert(ym & SP_HIDDEN_BIT); 1104e9561b2SMarkos Chandras 1114e9561b2SMarkos Chandras /* Compare signs */ 1124e9561b2SMarkos Chandras if (xs > ys) 1134e9561b2SMarkos Chandras return x; 1144e9561b2SMarkos Chandras else if (xs < ys) 1154e9561b2SMarkos Chandras return y; 1164e9561b2SMarkos Chandras 117aabf5cf0SAleksandar Markovic /* Signs of inputs are the same, let's compare exponents */ 118aabf5cf0SAleksandar Markovic if (xs == 0) { 119aabf5cf0SAleksandar Markovic /* Inputs are both positive */ 1204e9561b2SMarkos Chandras if (xe > ye) 1214e9561b2SMarkos Chandras return y; 1224e9561b2SMarkos Chandras else if (xe < ye) 1234e9561b2SMarkos Chandras return x; 124aabf5cf0SAleksandar Markovic } else { 125aabf5cf0SAleksandar Markovic /* Inputs are both negative */ 126aabf5cf0SAleksandar Markovic if (xe > ye) 127aabf5cf0SAleksandar Markovic return x; 128aabf5cf0SAleksandar Markovic else if (xe < ye) 129aabf5cf0SAleksandar Markovic return y; 130aabf5cf0SAleksandar Markovic } 1314e9561b2SMarkos Chandras 132aabf5cf0SAleksandar Markovic /* Signs and exponents of inputs are equal, let's compare mantissas */ 133aabf5cf0SAleksandar Markovic if (xs == 0) { 134aabf5cf0SAleksandar Markovic /* Inputs are both positive, with equal signs and exponents */ 1354e9561b2SMarkos Chandras if (xm <= ym) 1364e9561b2SMarkos Chandras return x; 1374e9561b2SMarkos Chandras return y; 1384e9561b2SMarkos Chandras } 139aabf5cf0SAleksandar Markovic /* Inputs are both negative, with equal signs and exponents */ 140aabf5cf0SAleksandar Markovic if (xm <= ym) 141aabf5cf0SAleksandar Markovic return y; 142aabf5cf0SAleksandar Markovic return x; 143aabf5cf0SAleksandar Markovic } 1444e9561b2SMarkos Chandras 1454e9561b2SMarkos Chandras union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y) 1464e9561b2SMarkos Chandras { 1474e9561b2SMarkos Chandras COMPXSP; 1484e9561b2SMarkos Chandras COMPYSP; 1494e9561b2SMarkos Chandras 1504e9561b2SMarkos Chandras EXPLODEXSP; 1514e9561b2SMarkos Chandras EXPLODEYSP; 1524e9561b2SMarkos Chandras 1534e9561b2SMarkos Chandras FLUSHXSP; 1544e9561b2SMarkos Chandras FLUSHYSP; 1554e9561b2SMarkos Chandras 1564e9561b2SMarkos Chandras ieee754_clearcx(); 1574e9561b2SMarkos Chandras 1584e9561b2SMarkos Chandras switch (CLPAIR(xc, yc)) { 1594e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): 1604e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): 1614e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): 1624e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): 1634e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): 1644e9561b2SMarkos Chandras return ieee754sp_nanxcpt(y); 1654e9561b2SMarkos Chandras 1664e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): 1674e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): 1684e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): 1694e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): 1704e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): 1714e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): 1724e9561b2SMarkos Chandras return ieee754sp_nanxcpt(x); 1734e9561b2SMarkos Chandras 174e78bf0dcSAleksandar Markovic /* 175e78bf0dcSAleksandar Markovic * Quiet NaN handling 176e78bf0dcSAleksandar Markovic */ 177e78bf0dcSAleksandar Markovic 178e78bf0dcSAleksandar Markovic /* 179e78bf0dcSAleksandar Markovic * The case of both inputs quiet NaNs 180e78bf0dcSAleksandar Markovic */ 181e78bf0dcSAleksandar Markovic case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): 182e78bf0dcSAleksandar Markovic return x; 183e78bf0dcSAleksandar Markovic 184e78bf0dcSAleksandar Markovic /* 185e78bf0dcSAleksandar Markovic * The cases of exactly one input quiet NaN (numbers 186e78bf0dcSAleksandar Markovic * are here preferred as returned values to NaNs) 187e78bf0dcSAleksandar Markovic */ 1884e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): 1894e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): 1904e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): 1914e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): 1924e9561b2SMarkos Chandras return x; 1934e9561b2SMarkos Chandras 1944e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): 1954e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): 1964e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): 1974e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): 1984e9561b2SMarkos Chandras return y; 1994e9561b2SMarkos Chandras 2004e9561b2SMarkos Chandras /* 2014e9561b2SMarkos Chandras * Infinity and zero handling 2024e9561b2SMarkos Chandras */ 2033444c4ebSAleksandar Markovic case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): 2043444c4ebSAleksandar Markovic return ieee754sp_inf(xs | ys); 2053444c4ebSAleksandar Markovic 2064e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): 2074e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): 2084e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): 2094e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): 2104e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): 211304bfe47SAleksandar Markovic return y; 2124e9561b2SMarkos Chandras 2134e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): 2144e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): 2154e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): 2164e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): 2174e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): 218304bfe47SAleksandar Markovic return x; 2194e9561b2SMarkos Chandras 2204e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): 22115560a58SAleksandar Markovic return ieee754sp_zero(xs | ys); 2224e9561b2SMarkos Chandras 2234e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): 2244e9561b2SMarkos Chandras SPDNORMX; 2252a14b21aSAleksandar Markovic /* fall through */ 2264e9561b2SMarkos Chandras 2274e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): 2284e9561b2SMarkos Chandras SPDNORMY; 2294e9561b2SMarkos Chandras break; 2304e9561b2SMarkos Chandras 2314e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): 2324e9561b2SMarkos Chandras SPDNORMX; 2334e9561b2SMarkos Chandras } 2344e9561b2SMarkos Chandras 2354e9561b2SMarkos Chandras /* Finally get to do some computation */ 2364e9561b2SMarkos Chandras 2374e9561b2SMarkos Chandras assert(xm & SP_HIDDEN_BIT); 2384e9561b2SMarkos Chandras assert(ym & SP_HIDDEN_BIT); 2394e9561b2SMarkos Chandras 2404e9561b2SMarkos Chandras /* Compare exponent */ 2414e9561b2SMarkos Chandras if (xe > ye) 2424e9561b2SMarkos Chandras return y; 2434e9561b2SMarkos Chandras else if (xe < ye) 2444e9561b2SMarkos Chandras return x; 2454e9561b2SMarkos Chandras 2464e9561b2SMarkos Chandras /* Compare mantissa */ 2471a41b3b4SAleksandar Markovic if (xm < ym) 2481a41b3b4SAleksandar Markovic return x; 2491a41b3b4SAleksandar Markovic else if (xm > ym) 2501a41b3b4SAleksandar Markovic return y; 2511a41b3b4SAleksandar Markovic else if (xs == 1) 2524e9561b2SMarkos Chandras return x; 2534e9561b2SMarkos Chandras return y; 2544e9561b2SMarkos Chandras } 255