1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * IEEE754 floating point arithmetic 4 * double precision: MIN{,A}.f 5 * MIN : Scalar Floating-Point Minimum 6 * MINA: Scalar Floating-Point argument with Minimum Absolute Value 7 * 8 * MIN.D : FPR[fd] = minNum(FPR[fs],FPR[ft]) 9 * MINA.D: 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 "ieee754dp.h" 17 18 union ieee754dp ieee754dp_fmin(union ieee754dp x, union ieee754dp y) 19 { 20 COMPXDP; 21 COMPYDP; 22 23 EXPLODEXDP; 24 EXPLODEYDP; 25 26 FLUSHXDP; 27 FLUSHYDP; 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 ieee754dp_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 ieee754dp_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 ieee754dp_zero(xs | ys); 93 94 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): 95 DPDNORMX; 96 /* fall through */ 97 98 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): 99 DPDNORMY; 100 break; 101 102 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): 103 DPDNORMX; 104 } 105 106 /* Finally get to do some computation */ 107 108 assert(xm & DP_HIDDEN_BIT); 109 assert(ym & DP_HIDDEN_BIT); 110 111 /* Compare signs */ 112 if (xs > ys) 113 return x; 114 else if (xs < ys) 115 return y; 116 117 /* Signs of inputs are the same, let's compare exponents */ 118 if (xs == 0) { 119 /* Inputs are both positive */ 120 if (xe > ye) 121 return y; 122 else if (xe < ye) 123 return x; 124 } else { 125 /* Inputs are both negative */ 126 if (xe > ye) 127 return x; 128 else if (xe < ye) 129 return y; 130 } 131 132 /* Signs and exponents of inputs are equal, let's compare mantissas */ 133 if (xs == 0) { 134 /* Inputs are both positive, with equal signs and exponents */ 135 if (xm <= ym) 136 return x; 137 return y; 138 } 139 /* Inputs are both negative, with equal signs and exponents */ 140 if (xm <= ym) 141 return y; 142 return x; 143 } 144 145 union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y) 146 { 147 COMPXDP; 148 COMPYDP; 149 150 EXPLODEXDP; 151 EXPLODEYDP; 152 153 FLUSHXDP; 154 FLUSHYDP; 155 156 ieee754_clearcx(); 157 158 switch (CLPAIR(xc, yc)) { 159 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): 160 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): 161 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): 162 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): 163 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): 164 return ieee754dp_nanxcpt(y); 165 166 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): 167 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): 168 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): 169 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): 170 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): 171 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): 172 return ieee754dp_nanxcpt(x); 173 174 /* 175 * Quiet NaN handling 176 */ 177 178 /* 179 * The case of both inputs quiet NaNs 180 */ 181 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): 182 return x; 183 184 /* 185 * The cases of exactly one input quiet NaN (numbers 186 * are here preferred as returned values to NaNs) 187 */ 188 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): 189 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): 190 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): 191 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): 192 return x; 193 194 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): 195 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): 196 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): 197 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): 198 return y; 199 200 /* 201 * Infinity and zero handling 202 */ 203 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): 204 return ieee754dp_inf(xs | ys); 205 206 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): 207 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): 208 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): 209 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): 210 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): 211 return y; 212 213 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): 214 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): 215 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): 216 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): 217 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): 218 return x; 219 220 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): 221 return ieee754dp_zero(xs | ys); 222 223 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): 224 DPDNORMX; 225 /* fall through */ 226 227 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): 228 DPDNORMY; 229 break; 230 231 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): 232 DPDNORMX; 233 } 234 235 /* Finally get to do some computation */ 236 237 assert(xm & DP_HIDDEN_BIT); 238 assert(ym & DP_HIDDEN_BIT); 239 240 /* Compare exponent */ 241 if (xe > ye) 242 return y; 243 else if (xe < ye) 244 return x; 245 246 /* Compare mantissa */ 247 if (xm < ym) 248 return x; 249 else if (xm > ym) 250 return y; 251 else if (xs == 1) 252 return x; 253 return y; 254 } 255