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; 994e9561b2SMarkos Chandras 1004e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): 1014e9561b2SMarkos Chandras SPDNORMY; 1024e9561b2SMarkos Chandras break; 1034e9561b2SMarkos Chandras 1044e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): 1054e9561b2SMarkos Chandras SPDNORMX; 1064e9561b2SMarkos Chandras } 1074e9561b2SMarkos Chandras 1084e9561b2SMarkos Chandras /* Finally get to do some computation */ 1094e9561b2SMarkos Chandras 1104e9561b2SMarkos Chandras assert(xm & SP_HIDDEN_BIT); 1114e9561b2SMarkos Chandras assert(ym & SP_HIDDEN_BIT); 1124e9561b2SMarkos Chandras 1134e9561b2SMarkos Chandras /* Compare signs */ 1144e9561b2SMarkos Chandras if (xs > ys) 1154e9561b2SMarkos Chandras return x; 1164e9561b2SMarkos Chandras else if (xs < ys) 1174e9561b2SMarkos Chandras return y; 1184e9561b2SMarkos Chandras 119*aabf5cf0SAleksandar Markovic /* Signs of inputs are the same, let's compare exponents */ 120*aabf5cf0SAleksandar Markovic if (xs == 0) { 121*aabf5cf0SAleksandar Markovic /* Inputs are both positive */ 1224e9561b2SMarkos Chandras if (xe > ye) 1234e9561b2SMarkos Chandras return y; 1244e9561b2SMarkos Chandras else if (xe < ye) 1254e9561b2SMarkos Chandras return x; 126*aabf5cf0SAleksandar Markovic } else { 127*aabf5cf0SAleksandar Markovic /* Inputs are both negative */ 128*aabf5cf0SAleksandar Markovic if (xe > ye) 129*aabf5cf0SAleksandar Markovic return x; 130*aabf5cf0SAleksandar Markovic else if (xe < ye) 131*aabf5cf0SAleksandar Markovic return y; 132*aabf5cf0SAleksandar Markovic } 1334e9561b2SMarkos Chandras 134*aabf5cf0SAleksandar Markovic /* Signs and exponents of inputs are equal, let's compare mantissas */ 135*aabf5cf0SAleksandar Markovic if (xs == 0) { 136*aabf5cf0SAleksandar Markovic /* Inputs are both positive, with equal signs and exponents */ 1374e9561b2SMarkos Chandras if (xm <= ym) 1384e9561b2SMarkos Chandras return x; 1394e9561b2SMarkos Chandras return y; 1404e9561b2SMarkos Chandras } 141*aabf5cf0SAleksandar Markovic /* Inputs are both negative, with equal signs and exponents */ 142*aabf5cf0SAleksandar Markovic if (xm <= ym) 143*aabf5cf0SAleksandar Markovic return y; 144*aabf5cf0SAleksandar Markovic return x; 145*aabf5cf0SAleksandar Markovic } 1464e9561b2SMarkos Chandras 1474e9561b2SMarkos Chandras union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y) 1484e9561b2SMarkos Chandras { 1494e9561b2SMarkos Chandras COMPXSP; 1504e9561b2SMarkos Chandras COMPYSP; 1514e9561b2SMarkos Chandras 1524e9561b2SMarkos Chandras EXPLODEXSP; 1534e9561b2SMarkos Chandras EXPLODEYSP; 1544e9561b2SMarkos Chandras 1554e9561b2SMarkos Chandras FLUSHXSP; 1564e9561b2SMarkos Chandras FLUSHYSP; 1574e9561b2SMarkos Chandras 1584e9561b2SMarkos Chandras ieee754_clearcx(); 1594e9561b2SMarkos Chandras 1604e9561b2SMarkos Chandras switch (CLPAIR(xc, yc)) { 1614e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): 1624e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): 1634e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): 1644e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): 1654e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): 1664e9561b2SMarkos Chandras return ieee754sp_nanxcpt(y); 1674e9561b2SMarkos Chandras 1684e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): 1694e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): 1704e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): 1714e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): 1724e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): 1734e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): 1744e9561b2SMarkos Chandras return ieee754sp_nanxcpt(x); 1754e9561b2SMarkos Chandras 176e78bf0dcSAleksandar Markovic /* 177e78bf0dcSAleksandar Markovic * Quiet NaN handling 178e78bf0dcSAleksandar Markovic */ 179e78bf0dcSAleksandar Markovic 180e78bf0dcSAleksandar Markovic /* 181e78bf0dcSAleksandar Markovic * The case of both inputs quiet NaNs 182e78bf0dcSAleksandar Markovic */ 183e78bf0dcSAleksandar Markovic case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): 184e78bf0dcSAleksandar Markovic return x; 185e78bf0dcSAleksandar Markovic 186e78bf0dcSAleksandar Markovic /* 187e78bf0dcSAleksandar Markovic * The cases of exactly one input quiet NaN (numbers 188e78bf0dcSAleksandar Markovic * are here preferred as returned values to NaNs) 189e78bf0dcSAleksandar Markovic */ 1904e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): 1914e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): 1924e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): 1934e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): 1944e9561b2SMarkos Chandras return x; 1954e9561b2SMarkos Chandras 1964e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): 1974e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): 1984e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): 1994e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): 2004e9561b2SMarkos Chandras return y; 2014e9561b2SMarkos Chandras 2024e9561b2SMarkos Chandras /* 2034e9561b2SMarkos Chandras * Infinity and zero handling 2044e9561b2SMarkos Chandras */ 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): 2104e9561b2SMarkos Chandras return x; 2114e9561b2SMarkos Chandras 2124e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): 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): 2184e9561b2SMarkos Chandras return y; 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; 2254e9561b2SMarkos Chandras 2264e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): 2274e9561b2SMarkos Chandras SPDNORMY; 2284e9561b2SMarkos Chandras break; 2294e9561b2SMarkos Chandras 2304e9561b2SMarkos Chandras case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): 2314e9561b2SMarkos Chandras SPDNORMX; 2324e9561b2SMarkos Chandras } 2334e9561b2SMarkos Chandras 2344e9561b2SMarkos Chandras /* Finally get to do some computation */ 2354e9561b2SMarkos Chandras 2364e9561b2SMarkos Chandras assert(xm & SP_HIDDEN_BIT); 2374e9561b2SMarkos Chandras assert(ym & SP_HIDDEN_BIT); 2384e9561b2SMarkos Chandras 2394e9561b2SMarkos Chandras /* Compare exponent */ 2404e9561b2SMarkos Chandras if (xe > ye) 2414e9561b2SMarkos Chandras return y; 2424e9561b2SMarkos Chandras else if (xe < ye) 2434e9561b2SMarkos Chandras return x; 2444e9561b2SMarkos Chandras 2454e9561b2SMarkos Chandras /* Compare mantissa */ 2464e9561b2SMarkos Chandras if (xm <= ym) 2474e9561b2SMarkos Chandras return x; 2484e9561b2SMarkos Chandras return y; 2494e9561b2SMarkos Chandras } 250