Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * IEEE754 floating point arithmetic
0004  * double precision: MIN{,A}.f
0005  * MIN : Scalar Floating-Point Minimum
0006  * MINA: Scalar Floating-Point argument with Minimum Absolute Value
0007  *
0008  * MIN.D : FPR[fd] = minNum(FPR[fs],FPR[ft])
0009  * MINA.D: FPR[fd] = maxNumMag(FPR[fs],FPR[ft])
0010  *
0011  * MIPS floating point support
0012  * Copyright (C) 2015 Imagination Technologies, Ltd.
0013  * Author: Markos Chandras <markos.chandras@imgtec.com>
0014  */
0015 
0016 #include "ieee754dp.h"
0017 
0018 union ieee754dp ieee754dp_fmin(union ieee754dp x, union ieee754dp y)
0019 {
0020     COMPXDP;
0021     COMPYDP;
0022 
0023     EXPLODEXDP;
0024     EXPLODEYDP;
0025 
0026     FLUSHXDP;
0027     FLUSHYDP;
0028 
0029     ieee754_clearcx();
0030 
0031     switch (CLPAIR(xc, yc)) {
0032     case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
0033     case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
0034     case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
0035     case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
0036     case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
0037         return ieee754dp_nanxcpt(y);
0038 
0039     case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
0040     case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
0041     case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
0042     case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
0043     case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
0044     case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
0045         return ieee754dp_nanxcpt(x);
0046 
0047     /*
0048      * Quiet NaN handling
0049      */
0050 
0051     /*
0052      *    The case of both inputs quiet NaNs
0053      */
0054     case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
0055         return x;
0056 
0057     /*
0058      *    The cases of exactly one input quiet NaN (numbers
0059      *    are here preferred as returned values to NaNs)
0060      */
0061     case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
0062     case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
0063     case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
0064     case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
0065         return x;
0066 
0067     case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
0068     case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
0069     case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
0070     case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
0071         return y;
0072 
0073     /*
0074      * Infinity and zero handling
0075      */
0076     case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
0077     case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
0078     case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
0079     case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
0080     case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
0081         return xs ? x : y;
0082 
0083     case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
0084     case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
0085     case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
0086     case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
0087     case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
0088     case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
0089         return ys ? y : x;
0090 
0091     case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
0092         return ieee754dp_zero(xs | ys);
0093 
0094     case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
0095         DPDNORMX;
0096         fallthrough;
0097     case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
0098         DPDNORMY;
0099         break;
0100 
0101     case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
0102         DPDNORMX;
0103     }
0104 
0105     /* Finally get to do some computation */
0106 
0107     assert(xm & DP_HIDDEN_BIT);
0108     assert(ym & DP_HIDDEN_BIT);
0109 
0110     /* Compare signs */
0111     if (xs > ys)
0112         return x;
0113     else if (xs < ys)
0114         return y;
0115 
0116     /* Signs of inputs are the same, let's compare exponents */
0117     if (xs == 0) {
0118         /* Inputs are both positive */
0119         if (xe > ye)
0120             return y;
0121         else if (xe < ye)
0122             return x;
0123     } else {
0124         /* Inputs are both negative */
0125         if (xe > ye)
0126             return x;
0127         else if (xe < ye)
0128             return y;
0129     }
0130 
0131     /* Signs and exponents of inputs are equal, let's compare mantissas */
0132     if (xs == 0) {
0133         /* Inputs are both positive, with equal signs and exponents */
0134         if (xm <= ym)
0135             return x;
0136         return y;
0137     }
0138     /* Inputs are both negative, with equal signs and exponents */
0139     if (xm <= ym)
0140         return y;
0141     return x;
0142 }
0143 
0144 union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y)
0145 {
0146     COMPXDP;
0147     COMPYDP;
0148 
0149     EXPLODEXDP;
0150     EXPLODEYDP;
0151 
0152     FLUSHXDP;
0153     FLUSHYDP;
0154 
0155     ieee754_clearcx();
0156 
0157     switch (CLPAIR(xc, yc)) {
0158     case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
0159     case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
0160     case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
0161     case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
0162     case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
0163         return ieee754dp_nanxcpt(y);
0164 
0165     case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
0166     case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
0167     case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
0168     case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
0169     case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
0170     case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
0171         return ieee754dp_nanxcpt(x);
0172 
0173     /*
0174      * Quiet NaN handling
0175      */
0176 
0177     /*
0178      *    The case of both inputs quiet NaNs
0179      */
0180     case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
0181         return x;
0182 
0183     /*
0184      *    The cases of exactly one input quiet NaN (numbers
0185      *    are here preferred as returned values to NaNs)
0186      */
0187     case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
0188     case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
0189     case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
0190     case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
0191         return x;
0192 
0193     case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
0194     case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
0195     case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
0196     case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
0197         return y;
0198 
0199     /*
0200      * Infinity and zero handling
0201      */
0202     case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
0203         return ieee754dp_inf(xs | ys);
0204 
0205     case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
0206     case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
0207     case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
0208     case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
0209     case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
0210         return y;
0211 
0212     case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
0213     case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
0214     case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
0215     case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
0216     case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
0217         return x;
0218 
0219     case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
0220         return ieee754dp_zero(xs | ys);
0221 
0222     case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
0223         DPDNORMX;
0224         fallthrough;
0225     case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
0226         DPDNORMY;
0227         break;
0228 
0229     case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
0230         DPDNORMX;
0231     }
0232 
0233     /* Finally get to do some computation */
0234 
0235     assert(xm & DP_HIDDEN_BIT);
0236     assert(ym & DP_HIDDEN_BIT);
0237 
0238     /* Compare exponent */
0239     if (xe > ye)
0240         return y;
0241     else if (xe < ye)
0242         return x;
0243 
0244     /* Compare mantissa */
0245     if (xm < ym)
0246         return x;
0247     else if (xm > ym)
0248         return y;
0249     else if (xs == 1)
0250         return x;
0251     return y;
0252 }