14e9561b2SMarkos Chandras /* 24e9561b2SMarkos Chandras * IEEE754 floating point arithmetic 34e9561b2SMarkos Chandras * single precision: MIN{,A}.f 44e9561b2SMarkos Chandras * MIN : Scalar Floating-Point Minimum 54e9561b2SMarkos Chandras * MINA: Scalar Floating-Point argument with Minimum Absolute Value 64e9561b2SMarkos Chandras * 74e9561b2SMarkos Chandras * MIN.S : FPR[fd] = minNum(FPR[fs],FPR[ft]) 84e9561b2SMarkos Chandras * MINA.S: FPR[fd] = maxNumMag(FPR[fs],FPR[ft]) 94e9561b2SMarkos Chandras * 104e9561b2SMarkos Chandras * MIPS floating point support 114e9561b2SMarkos Chandras * Copyright (C) 2015 Imagination Technologies, Ltd. 124e9561b2SMarkos Chandras * Author: Markos Chandras <markos.chandras@imgtec.com> 134e9561b2SMarkos Chandras * 144e9561b2SMarkos Chandras * This program is free software; you can distribute it and/or modify it 154e9561b2SMarkos Chandras * under the terms of the GNU General Public License as published by the 164e9561b2SMarkos Chandras * Free Software Foundation; version 2 of the License. 174e9561b2SMarkos Chandras */ 184e9561b2SMarkos Chandras 194e9561b2SMarkos Chandras #include "ieee754sp.h" 204e9561b2SMarkos Chandras 214e9561b2SMarkos Chandras union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y) 224e9561b2SMarkos Chandras { 234e9561b2SMarkos Chandras COMPXSP; 244e9561b2SMarkos Chandras COMPYSP; 254e9561b2SMarkos Chandras 264e9561b2SMarkos Chandras EXPLODEXSP; 274e9561b2SMarkos Chandras EXPLODEYSP; 284e9561b2SMarkos Chandras 294e9561b2SMarkos Chandras FLUSHXSP; 304e9561b2SMarkos Chandras FLUSHYSP; 314e9561b2SMarkos Chandras 324e9561b2SMarkos Chandras ieee754_clearcx(); 334e9561b2SMarkos Chandras 344e9561b2SMarkos Chandras switch (CLPAIR(xc, yc)) { 354e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): 364e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): 374e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): 384e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): 394e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): 404e9561b2SMarkos Chandras return ieee754sp_nanxcpt(y); 414e9561b2SMarkos Chandras 424e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): 434e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): 444e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): 454e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): 464e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): 474e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): 484e9561b2SMarkos Chandras return ieee754sp_nanxcpt(x); 494e9561b2SMarkos Chandras 50e78bf0dcSAleksandar Markovic /* 51e78bf0dcSAleksandar Markovic * Quiet NaN handling 52e78bf0dcSAleksandar Markovic */ 53e78bf0dcSAleksandar Markovic 54e78bf0dcSAleksandar Markovic /* 55e78bf0dcSAleksandar Markovic * The case of both inputs quiet NaNs 56e78bf0dcSAleksandar Markovic */ 57e78bf0dcSAleksandar Markovic case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): 58e78bf0dcSAleksandar Markovic return x; 59e78bf0dcSAleksandar Markovic 60e78bf0dcSAleksandar Markovic /* 61e78bf0dcSAleksandar Markovic * The cases of exactly one input quiet NaN (numbers 62e78bf0dcSAleksandar Markovic * are here preferred as returned values to NaNs) 63e78bf0dcSAleksandar Markovic */ 644e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): 654e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): 664e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): 674e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): 684e9561b2SMarkos Chandras return x; 694e9561b2SMarkos Chandras 704e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): 714e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): 724e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): 734e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): 744e9561b2SMarkos Chandras return y; 754e9561b2SMarkos Chandras 764e9561b2SMarkos Chandras /* 774e9561b2SMarkos Chandras * Infinity and zero handling 784e9561b2SMarkos Chandras */ 794e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): 804e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): 814e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): 824e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): 834e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): 844e9561b2SMarkos Chandras return xs ? x : y; 854e9561b2SMarkos Chandras 864e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): 874e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): 884e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): 894e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): 904e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): 914e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): 924e9561b2SMarkos Chandras return ys ? y : x; 934e9561b2SMarkos Chandras 944e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): 9515560a58SAleksandar Markovic return ieee754sp_zero(xs | ys); 964e9561b2SMarkos Chandras 974e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): 984e9561b2SMarkos Chandras SPDNORMX; 99*2a14b21aSAleksandar Markovic /* fall through */ 1004e9561b2SMarkos Chandras 1014e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): 1024e9561b2SMarkos Chandras SPDNORMY; 1034e9561b2SMarkos Chandras break; 1044e9561b2SMarkos Chandras 1054e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): 1064e9561b2SMarkos Chandras SPDNORMX; 1074e9561b2SMarkos Chandras } 1084e9561b2SMarkos Chandras 1094e9561b2SMarkos Chandras /* Finally get to do some computation */ 1104e9561b2SMarkos Chandras 1114e9561b2SMarkos Chandras assert(xm & SP_HIDDEN_BIT); 1124e9561b2SMarkos Chandras assert(ym & SP_HIDDEN_BIT); 1134e9561b2SMarkos Chandras 1144e9561b2SMarkos Chandras /* Compare signs */ 1154e9561b2SMarkos Chandras if (xs > ys) 1164e9561b2SMarkos Chandras return x; 1174e9561b2SMarkos Chandras else if (xs < ys) 1184e9561b2SMarkos Chandras return y; 1194e9561b2SMarkos Chandras 120aabf5cf0SAleksandar Markovic /* Signs of inputs are the same, let's compare exponents */ 121aabf5cf0SAleksandar Markovic if (xs == 0) { 122aabf5cf0SAleksandar Markovic /* Inputs are both positive */ 1234e9561b2SMarkos Chandras if (xe > ye) 1244e9561b2SMarkos Chandras return y; 1254e9561b2SMarkos Chandras else if (xe < ye) 1264e9561b2SMarkos Chandras return x; 127aabf5cf0SAleksandar Markovic } else { 128aabf5cf0SAleksandar Markovic /* Inputs are both negative */ 129aabf5cf0SAleksandar Markovic if (xe > ye) 130aabf5cf0SAleksandar Markovic return x; 131aabf5cf0SAleksandar Markovic else if (xe < ye) 132aabf5cf0SAleksandar Markovic return y; 133aabf5cf0SAleksandar Markovic } 1344e9561b2SMarkos Chandras 135aabf5cf0SAleksandar Markovic /* Signs and exponents of inputs are equal, let's compare mantissas */ 136aabf5cf0SAleksandar Markovic if (xs == 0) { 137aabf5cf0SAleksandar Markovic /* Inputs are both positive, with equal signs and exponents */ 1384e9561b2SMarkos Chandras if (xm <= ym) 1394e9561b2SMarkos Chandras return x; 1404e9561b2SMarkos Chandras return y; 1414e9561b2SMarkos Chandras } 142aabf5cf0SAleksandar Markovic /* Inputs are both negative, with equal signs and exponents */ 143aabf5cf0SAleksandar Markovic if (xm <= ym) 144aabf5cf0SAleksandar Markovic return y; 145aabf5cf0SAleksandar Markovic return x; 146aabf5cf0SAleksandar Markovic } 1474e9561b2SMarkos Chandras 1484e9561b2SMarkos Chandras union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y) 1494e9561b2SMarkos Chandras { 1504e9561b2SMarkos Chandras COMPXSP; 1514e9561b2SMarkos Chandras COMPYSP; 1524e9561b2SMarkos Chandras 1534e9561b2SMarkos Chandras EXPLODEXSP; 1544e9561b2SMarkos Chandras EXPLODEYSP; 1554e9561b2SMarkos Chandras 1564e9561b2SMarkos Chandras FLUSHXSP; 1574e9561b2SMarkos Chandras FLUSHYSP; 1584e9561b2SMarkos Chandras 1594e9561b2SMarkos Chandras ieee754_clearcx(); 1604e9561b2SMarkos Chandras 1614e9561b2SMarkos Chandras switch (CLPAIR(xc, yc)) { 1624e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): 1634e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): 1644e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): 1654e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): 1664e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): 1674e9561b2SMarkos Chandras return ieee754sp_nanxcpt(y); 1684e9561b2SMarkos Chandras 1694e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): 1704e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): 1714e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): 1724e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): 1734e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): 1744e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): 1754e9561b2SMarkos Chandras return ieee754sp_nanxcpt(x); 1764e9561b2SMarkos Chandras 177e78bf0dcSAleksandar Markovic /* 178e78bf0dcSAleksandar Markovic * Quiet NaN handling 179e78bf0dcSAleksandar Markovic */ 180e78bf0dcSAleksandar Markovic 181e78bf0dcSAleksandar Markovic /* 182e78bf0dcSAleksandar Markovic * The case of both inputs quiet NaNs 183e78bf0dcSAleksandar Markovic */ 184e78bf0dcSAleksandar Markovic case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): 185e78bf0dcSAleksandar Markovic return x; 186e78bf0dcSAleksandar Markovic 187e78bf0dcSAleksandar Markovic /* 188e78bf0dcSAleksandar Markovic * The cases of exactly one input quiet NaN (numbers 189e78bf0dcSAleksandar Markovic * are here preferred as returned values to NaNs) 190e78bf0dcSAleksandar Markovic */ 1914e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): 1924e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): 1934e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): 1944e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): 1954e9561b2SMarkos Chandras return x; 1964e9561b2SMarkos Chandras 1974e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): 1984e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): 1994e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): 2004e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): 2014e9561b2SMarkos Chandras return y; 2024e9561b2SMarkos Chandras 2034e9561b2SMarkos Chandras /* 2044e9561b2SMarkos Chandras * Infinity and zero handling 2054e9561b2SMarkos Chandras */ 2063444c4ebSAleksandar Markovic case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): 2073444c4ebSAleksandar Markovic return ieee754sp_inf(xs | ys); 2083444c4ebSAleksandar Markovic 2094e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): 2104e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): 2114e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): 2124e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): 2134e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): 214304bfe47SAleksandar Markovic return y; 2154e9561b2SMarkos Chandras 2164e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): 2174e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): 2184e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): 2194e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): 2204e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): 221304bfe47SAleksandar Markovic return x; 2224e9561b2SMarkos Chandras 2234e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): 22415560a58SAleksandar Markovic return ieee754sp_zero(xs | ys); 2254e9561b2SMarkos Chandras 2264e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): 2274e9561b2SMarkos Chandras SPDNORMX; 228*2a14b21aSAleksandar Markovic /* fall through */ 2294e9561b2SMarkos Chandras 2304e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): 2314e9561b2SMarkos Chandras SPDNORMY; 2324e9561b2SMarkos Chandras break; 2334e9561b2SMarkos Chandras 2344e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): 2354e9561b2SMarkos Chandras SPDNORMX; 2364e9561b2SMarkos Chandras } 2374e9561b2SMarkos Chandras 2384e9561b2SMarkos Chandras /* Finally get to do some computation */ 2394e9561b2SMarkos Chandras 2404e9561b2SMarkos Chandras assert(xm & SP_HIDDEN_BIT); 2414e9561b2SMarkos Chandras assert(ym & SP_HIDDEN_BIT); 2424e9561b2SMarkos Chandras 2434e9561b2SMarkos Chandras /* Compare exponent */ 2444e9561b2SMarkos Chandras if (xe > ye) 2454e9561b2SMarkos Chandras return y; 2464e9561b2SMarkos Chandras else if (xe < ye) 2474e9561b2SMarkos Chandras return x; 2484e9561b2SMarkos Chandras 2494e9561b2SMarkos Chandras /* Compare mantissa */ 2501a41b3b4SAleksandar Markovic if (xm < ym) 2511a41b3b4SAleksandar Markovic return x; 2521a41b3b4SAleksandar Markovic else if (xm > ym) 2531a41b3b4SAleksandar Markovic return y; 2541a41b3b4SAleksandar Markovic else if (xs == 1) 2554e9561b2SMarkos Chandras return x; 2564e9561b2SMarkos Chandras return y; 2574e9561b2SMarkos Chandras } 258