1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * IEEE754 floating point arithmetic 4 * single precision: MIN{,A}.f 5 * MIN : Scalar Floating-Point Minimum 6 * MINA: Scalar Floating-Point argument with Minimum Absolute Value 7 * 8 * MIN.S : FPR[fd] = minNum(FPR[fs],FPR[ft]) 9 * MINA.S: FPR[fd] = maxNumMag(FPR[fs],FPR[ft]) 10 * 11 * MIPS floating point support 12 * Copyright (C) 2015 Imagination Technologies, Ltd. 13 * Author: Markos Chandras <markos.chandras@imgtec.com> 14 */ 15 16 #include "ieee754sp.h" 17 18 union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y) 19 { 20 COMPXSP; 21 COMPYSP; 22 23 EXPLODEXSP; 24 EXPLODEYSP; 25 26 FLUSHXSP; 27 FLUSHYSP; 28 29 ieee754_clearcx(); 30 31 switch (CLPAIR(xc, yc)) { 32 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): 33 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): 34 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): 35 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): 36 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): 37 return ieee754sp_nanxcpt(y); 38 39 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): 40 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): 41 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): 42 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): 43 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): 44 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): 45 return ieee754sp_nanxcpt(x); 46 47 /* 48 * Quiet NaN handling 49 */ 50 51 /* 52 * The case of both inputs quiet NaNs 53 */ 54 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): 55 return x; 56 57 /* 58 * The cases of exactly one input quiet NaN (numbers 59 * are here preferred as returned values to NaNs) 60 */ 61 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): 62 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): 63 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): 64 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): 65 return x; 66 67 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): 68 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): 69 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): 70 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): 71 return y; 72 73 /* 74 * Infinity and zero handling 75 */ 76 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): 77 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): 78 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): 79 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): 80 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): 81 return xs ? x : y; 82 83 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): 84 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): 85 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): 86 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): 87 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): 88 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): 89 return ys ? y : x; 90 91 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): 92 return ieee754sp_zero(xs | ys); 93 94 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): 95 SPDNORMX; 96 fallthrough; 97 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): 98 SPDNORMY; 99 break; 100 101 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): 102 SPDNORMX; 103 } 104 105 /* Finally get to do some computation */ 106 107 assert(xm & SP_HIDDEN_BIT); 108 assert(ym & SP_HIDDEN_BIT); 109 110 /* Compare signs */ 111 if (xs > ys) 112 return x; 113 else if (xs < ys) 114 return y; 115 116 /* Signs of inputs are the same, let's compare exponents */ 117 if (xs == 0) { 118 /* Inputs are both positive */ 119 if (xe > ye) 120 return y; 121 else if (xe < ye) 122 return x; 123 } else { 124 /* Inputs are both negative */ 125 if (xe > ye) 126 return x; 127 else if (xe < ye) 128 return y; 129 } 130 131 /* Signs and exponents of inputs are equal, let's compare mantissas */ 132 if (xs == 0) { 133 /* Inputs are both positive, with equal signs and exponents */ 134 if (xm <= ym) 135 return x; 136 return y; 137 } 138 /* Inputs are both negative, with equal signs and exponents */ 139 if (xm <= ym) 140 return y; 141 return x; 142 } 143 144 union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y) 145 { 146 COMPXSP; 147 COMPYSP; 148 149 EXPLODEXSP; 150 EXPLODEYSP; 151 152 FLUSHXSP; 153 FLUSHYSP; 154 155 ieee754_clearcx(); 156 157 switch (CLPAIR(xc, yc)) { 158 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): 159 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): 160 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): 161 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): 162 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): 163 return ieee754sp_nanxcpt(y); 164 165 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): 166 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): 167 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): 168 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): 169 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): 170 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): 171 return ieee754sp_nanxcpt(x); 172 173 /* 174 * Quiet NaN handling 175 */ 176 177 /* 178 * The case of both inputs quiet NaNs 179 */ 180 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): 181 return x; 182 183 /* 184 * The cases of exactly one input quiet NaN (numbers 185 * are here preferred as returned values to NaNs) 186 */ 187 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): 188 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): 189 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): 190 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): 191 return x; 192 193 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): 194 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): 195 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): 196 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): 197 return y; 198 199 /* 200 * Infinity and zero handling 201 */ 202 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): 203 return ieee754sp_inf(xs | ys); 204 205 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): 206 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): 207 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): 208 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): 209 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): 210 return y; 211 212 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): 213 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): 214 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): 215 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): 216 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): 217 return x; 218 219 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): 220 return ieee754sp_zero(xs | ys); 221 222 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): 223 SPDNORMX; 224 fallthrough; 225 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): 226 SPDNORMY; 227 break; 228 229 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): 230 SPDNORMX; 231 } 232 233 /* Finally get to do some computation */ 234 235 assert(xm & SP_HIDDEN_BIT); 236 assert(ym & SP_HIDDEN_BIT); 237 238 /* Compare exponent */ 239 if (xe > ye) 240 return y; 241 else if (xe < ye) 242 return x; 243 244 /* Compare mantissa */ 245 if (xm < ym) 246 return x; 247 else if (xm > ym) 248 return y; 249 else if (xs == 1) 250 return x; 251 return y; 252 } 253