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 /* fall through */ 100 101 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): 102 SPDNORMY; 103 break; 104 105 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): 106 SPDNORMX; 107 } 108 109 /* Finally get to do some computation */ 110 111 assert(xm & SP_HIDDEN_BIT); 112 assert(ym & SP_HIDDEN_BIT); 113 114 /* Compare signs */ 115 if (xs > ys) 116 return y; 117 else if (xs < ys) 118 return x; 119 120 /* Signs of inputs are equal, let's compare exponents */ 121 if (xs == 0) { 122 /* Inputs are both positive */ 123 if (xe > ye) 124 return x; 125 else if (xe < ye) 126 return y; 127 } else { 128 /* Inputs are both negative */ 129 if (xe > ye) 130 return y; 131 else if (xe < ye) 132 return x; 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 y; 140 return x; 141 } 142 /* Inputs are both negative, with equal signs and exponents */ 143 if (xm <= ym) 144 return x; 145 return y; 146 } 147 148 union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y) 149 { 150 COMPXSP; 151 COMPYSP; 152 153 EXPLODEXSP; 154 EXPLODEYSP; 155 156 FLUSHXSP; 157 FLUSHYSP; 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 ieee754sp_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 ieee754sp_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 ieee754sp_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 x; 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 y; 222 223 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): 224 return ieee754sp_zero(xs & ys); 225 226 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): 227 SPDNORMX; 228 /* fall through */ 229 230 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): 231 SPDNORMY; 232 break; 233 234 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): 235 SPDNORMX; 236 } 237 238 /* Finally get to do some computation */ 239 240 assert(xm & SP_HIDDEN_BIT); 241 assert(ym & SP_HIDDEN_BIT); 242 243 /* Compare exponent */ 244 if (xe > ye) 245 return x; 246 else if (xe < ye) 247 return y; 248 249 /* Compare mantissa */ 250 if (xm < ym) 251 return y; 252 else if (xm > ym) 253 return x; 254 else if (xs == 0) 255 return x; 256 return y; 257 } 258