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_fmax(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 /* 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 ieee754dp_zero(1); 86 87 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): 88 DPDNORMX; 89 90 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): 91 DPDNORMY; 92 break; 93 94 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): 95 DPDNORMX; 96 } 97 98 /* Finally get to do some computation */ 99 100 assert(xm & DP_HIDDEN_BIT); 101 assert(ym & DP_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 121 union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y) 122 { 123 COMPXDP; 124 COMPYDP; 125 126 EXPLODEXDP; 127 EXPLODEYDP; 128 129 FLUSHXDP; 130 FLUSHYDP; 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 ieee754dp_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 ieee754dp_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 ieee754dp_zero(1); 186 187 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): 188 DPDNORMX; 189 190 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): 191 DPDNORMY; 192 break; 193 194 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): 195 DPDNORMX; 196 } 197 198 /* Finally get to do some computation */ 199 200 assert(xm & DP_HIDDEN_BIT); 201 assert(ym & DP_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