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