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 21union 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 /* numbers are preferred to NaNs */ 51 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): 52 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): 53 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): 54 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): 55 return x; 56 57 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): 58 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): 59 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): 60 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): 61 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): 62 return y; 63 64 /* 65 * Infinity and zero handling 66 */ 67 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): 68 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): 69 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): 70 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): 71 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): 72 return xs ? y : x; 73 74 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): 75 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): 76 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): 77 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): 78 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): 79 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): 80 return ys ? x : y; 81 82 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): 83 if (xs == ys) 84 return x; 85 return ieee754sp_zero(1); 86 87 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): 88 SPDNORMX; 89 90 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): 91 SPDNORMY; 92 break; 93 94 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): 95 SPDNORMX; 96 } 97 98 /* Finally get to do some computation */ 99 100 assert(xm & SP_HIDDEN_BIT); 101 assert(ym & SP_HIDDEN_BIT); 102 103 /* Compare signs */ 104 if (xs > ys) 105 return y; 106 else if (xs < ys) 107 return x; 108 109 /* Compare exponent */ 110 if (xe > ye) 111 return x; 112 else if (xe < ye) 113 return y; 114 115 /* Compare mantissa */ 116 if (xm <= ym) 117 return y; 118 return x; 119} 120 121union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y) 122{ 123 COMPXSP; 124 COMPYSP; 125 126 EXPLODEXSP; 127 EXPLODEYSP; 128 129 FLUSHXSP; 130 FLUSHYSP; 131 132 ieee754_clearcx(); 133 134 switch (CLPAIR(xc, yc)) { 135 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): 136 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): 137 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): 138 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): 139 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): 140 return ieee754sp_nanxcpt(y); 141 142 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): 143 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): 144 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): 145 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): 146 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): 147 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): 148 return ieee754sp_nanxcpt(x); 149 150 /* numbers are preferred to NaNs */ 151 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): 152 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): 153 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): 154 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): 155 return x; 156 157 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): 158 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): 159 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): 160 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): 161 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): 162 return y; 163 164 /* 165 * Infinity and zero handling 166 */ 167 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): 168 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): 169 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): 170 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): 171 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): 172 return x; 173 174 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): 175 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): 176 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): 177 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): 178 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): 179 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): 180 return y; 181 182 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): 183 if (xs == ys) 184 return x; 185 return ieee754sp_zero(1); 186 187 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): 188 SPDNORMX; 189 190 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): 191 SPDNORMY; 192 break; 193 194 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): 195 SPDNORMX; 196 } 197 198 /* Finally get to do some computation */ 199 200 assert(xm & SP_HIDDEN_BIT); 201 assert(ym & SP_HIDDEN_BIT); 202 203 /* Compare exponent */ 204 if (xe > ye) 205 return x; 206 else if (xe < ye) 207 return y; 208 209 /* Compare mantissa */ 210 if (xm <= ym) 211 return y; 212 return x; 213} 214