dp_fmax.c (6714B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * IEEE754 floating point arithmetic 4 * double precision: MIN{,A}.f 5 * MIN : Scalar Floating-Point Minimum 6 * MINA: Scalar Floating-Point argument with Minimum Absolute Value 7 * 8 * MIN.D : FPR[fd] = minNum(FPR[fs],FPR[ft]) 9 * MINA.D: 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 "ieee754dp.h" 17 18union ieee754dp ieee754dp_fmax(union ieee754dp x, union ieee754dp y) 19{ 20 COMPXDP; 21 COMPYDP; 22 23 EXPLODEXDP; 24 EXPLODEYDP; 25 26 FLUSHXDP; 27 FLUSHYDP; 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 ieee754dp_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 ieee754dp_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 ieee754dp_zero(xs & ys); 93 94 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): 95 DPDNORMX; 96 fallthrough; 97 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): 98 DPDNORMY; 99 break; 100 101 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): 102 DPDNORMX; 103 } 104 105 /* Finally get to do some computation */ 106 107 assert(xm & DP_HIDDEN_BIT); 108 assert(ym & DP_HIDDEN_BIT); 109 110 /* Compare signs */ 111 if (xs > ys) 112 return y; 113 else if (xs < ys) 114 return x; 115 116 /* Signs of inputs are equal, let's compare exponents */ 117 if (xs == 0) { 118 /* Inputs are both positive */ 119 if (xe > ye) 120 return x; 121 else if (xe < ye) 122 return y; 123 } else { 124 /* Inputs are both negative */ 125 if (xe > ye) 126 return y; 127 else if (xe < ye) 128 return x; 129 } 130 131 /* Signs and exponents of inputs are equal, let's compare mantissas */ 132 if (xs == 0) { 133 /* Inputs are both positive, with equal signs and exponents */ 134 if (xm <= ym) 135 return y; 136 return x; 137 } 138 /* Inputs are both negative, with equal signs and exponents */ 139 if (xm <= ym) 140 return x; 141 return y; 142} 143 144union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y) 145{ 146 COMPXDP; 147 COMPYDP; 148 149 EXPLODEXDP; 150 EXPLODEYDP; 151 152 FLUSHXDP; 153 FLUSHYDP; 154 155 ieee754_clearcx(); 156 157 switch (CLPAIR(xc, yc)) { 158 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): 159 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): 160 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): 161 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): 162 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): 163 return ieee754dp_nanxcpt(y); 164 165 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): 166 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): 167 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): 168 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): 169 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): 170 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): 171 return ieee754dp_nanxcpt(x); 172 173 /* 174 * Quiet NaN handling 175 */ 176 177 /* 178 * The case of both inputs quiet NaNs 179 */ 180 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): 181 return x; 182 183 /* 184 * The cases of exactly one input quiet NaN (numbers 185 * are here preferred as returned values to NaNs) 186 */ 187 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): 188 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): 189 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): 190 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): 191 return x; 192 193 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): 194 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): 195 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): 196 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): 197 return y; 198 199 /* 200 * Infinity and zero handling 201 */ 202 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): 203 return ieee754dp_inf(xs & ys); 204 205 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): 206 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): 207 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): 208 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): 209 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): 210 return x; 211 212 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): 213 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): 214 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): 215 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): 216 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): 217 return y; 218 219 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): 220 return ieee754dp_zero(xs & ys); 221 222 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): 223 DPDNORMX; 224 fallthrough; 225 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): 226 DPDNORMY; 227 break; 228 229 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): 230 DPDNORMX; 231 } 232 233 /* Finally get to do some computation */ 234 235 assert(xm & DP_HIDDEN_BIT); 236 assert(ym & DP_HIDDEN_BIT); 237 238 /* Compare exponent */ 239 if (xe > ye) 240 return x; 241 else if (xe < ye) 242 return y; 243 244 /* Compare mantissa */ 245 if (xm < ym) 246 return y; 247 else if (xm > ym) 248 return x; 249 else if (xs == 0) 250 return x; 251 return y; 252}