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