Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * IEEE754 floating point arithmetic
0004  * single precision: MAX{,A}.f
0005  * MAX : Scalar Floating-Point Maximum
0006  * MAXA: Scalar Floating-Point argument with Maximum Absolute Value
0007  *
0008  * MAX.S : FPR[fd] = maxNum(FPR[fs],FPR[ft])
0009  * MAXA.S: 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 "ieee754sp.h"
0017 
0018 union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y)
0019 {
0020     COMPXSP;
0021     COMPYSP;
0022 
0023     EXPLODEXSP;
0024     EXPLODEYSP;
0025 
0026     FLUSHXSP;
0027     FLUSHYSP;
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 ieee754sp_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 ieee754sp_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 ? y : x;
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 ? x : y;
0090 
0091     case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
0092         return ieee754sp_zero(xs & ys);
0093 
0094     case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
0095         SPDNORMX;
0096         fallthrough;
0097     case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
0098         SPDNORMY;
0099         break;
0100 
0101     case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
0102         SPDNORMX;
0103     }
0104 
0105     /* Finally get to do some computation */
0106 
0107     assert(xm & SP_HIDDEN_BIT);
0108     assert(ym & SP_HIDDEN_BIT);
0109 
0110     /* Compare signs */
0111     if (xs > ys)
0112         return y;
0113     else if (xs < ys)
0114         return x;
0115 
0116     /* Signs of inputs are equal, let's compare exponents */
0117     if (xs == 0) {
0118         /* Inputs are both positive */
0119         if (xe > ye)
0120             return x;
0121         else if (xe < ye)
0122             return y;
0123     } else {
0124         /* Inputs are both negative */
0125         if (xe > ye)
0126             return y;
0127         else if (xe < ye)
0128             return x;
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 y;
0136         return x;
0137     }
0138     /* Inputs are both negative, with equal signs and exponents */
0139     if (xm <= ym)
0140         return x;
0141     return y;
0142 }
0143 
0144 union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y)
0145 {
0146     COMPXSP;
0147     COMPYSP;
0148 
0149     EXPLODEXSP;
0150     EXPLODEYSP;
0151 
0152     FLUSHXSP;
0153     FLUSHYSP;
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 ieee754sp_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 ieee754sp_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 ieee754sp_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 x;
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 y;
0218 
0219     case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
0220         return ieee754sp_zero(xs & ys);
0221 
0222     case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
0223         SPDNORMX;
0224         fallthrough;
0225     case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
0226         SPDNORMY;
0227         break;
0228 
0229     case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
0230         SPDNORMX;
0231     }
0232 
0233     /* Finally get to do some computation */
0234 
0235     assert(xm & SP_HIDDEN_BIT);
0236     assert(ym & SP_HIDDEN_BIT);
0237 
0238     /* Compare exponent */
0239     if (xe > ye)
0240         return x;
0241     else if (xe < ye)
0242         return y;
0243 
0244     /* Compare mantissa */
0245     if (xm < ym)
0246         return y;
0247     else if (xm > ym)
0248         return x;
0249     else if (xs == 0)
0250         return x;
0251     return y;
0252 }