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