1 /* 2 * IEEE754 floating point arithmetic 3 * single precision: MAX{,A}.f 4 * MAX : Scalar Floating-Point Maximum 5 * MAXA: Scalar Floating-Point argument with Maximum Absolute Value 6 * 7 * MAX.S : FPR[fd] = maxNum(FPR[fs],FPR[ft]) 8 * MAXA.S: 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 "ieee754sp.h" 20 21 union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y) 22 { 23 COMPXSP; 24 COMPYSP; 25 26 EXPLODEXSP; 27 EXPLODEYSP; 28 29 FLUSHXSP; 30 FLUSHYSP; 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 ieee754sp_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 ieee754sp_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 ? y : x; 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 ? x : y; 93 94 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): 95 return ieee754sp_zero(xs & ys); 96 97 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): 98 SPDNORMX; 99 100 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): 101 SPDNORMY; 102 break; 103 104 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): 105 SPDNORMX; 106 } 107 108 /* Finally get to do some computation */ 109 110 assert(xm & SP_HIDDEN_BIT); 111 assert(ym & SP_HIDDEN_BIT); 112 113 /* Compare signs */ 114 if (xs > ys) 115 return y; 116 else if (xs < ys) 117 return x; 118 119 /* Signs of inputs are equal, let's compare exponents */ 120 if (xs == 0) { 121 /* Inputs are both positive */ 122 if (xe > ye) 123 return x; 124 else if (xe < ye) 125 return y; 126 } else { 127 /* Inputs are both negative */ 128 if (xe > ye) 129 return y; 130 else if (xe < ye) 131 return x; 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 y; 139 return x; 140 } 141 /* Inputs are both negative, with equal signs and exponents */ 142 if (xm <= ym) 143 return x; 144 return y; 145 } 146 147 union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y) 148 { 149 COMPXSP; 150 COMPYSP; 151 152 EXPLODEXSP; 153 EXPLODEYSP; 154 155 FLUSHXSP; 156 FLUSHYSP; 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 ieee754sp_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 ieee754sp_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 ieee754sp_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 x; 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 y; 221 222 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): 223 return ieee754sp_zero(xs & ys); 224 225 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): 226 SPDNORMX; 227 228 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): 229 SPDNORMY; 230 break; 231 232 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): 233 SPDNORMX; 234 } 235 236 /* Finally get to do some computation */ 237 238 assert(xm & SP_HIDDEN_BIT); 239 assert(ym & SP_HIDDEN_BIT); 240 241 /* Compare exponent */ 242 if (xe > ye) 243 return x; 244 else if (xe < ye) 245 return y; 246 247 /* Compare mantissa */ 248 if (xm < ym) 249 return y; 250 else if (xm > ym) 251 return x; 252 else if (xs == 0) 253 return x; 254 return y; 255 } 256