linux/arch/mips/math-emu/dp_fmin.c
<<
>>
Prefs
   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_fmin(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 ? x : y;
  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 ? y : x;
  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 x;
 113        else if (xs < ys)
 114                return y;
 115
 116        /* Signs of inputs are the same, let's compare exponents */
 117        if (xs == 0) {
 118                /* Inputs are both positive */
 119                if (xe > ye)
 120                        return y;
 121                else if (xe < ye)
 122                        return x;
 123        } else {
 124                /* Inputs are both negative */
 125                if (xe > ye)
 126                        return x;
 127                else if (xe < ye)
 128                        return y;
 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 x;
 136                return y;
 137        }
 138        /* Inputs are both negative, with equal signs and exponents */
 139        if (xm <= ym)
 140                return y;
 141        return x;
 142}
 143
 144union ieee754dp ieee754dp_fmina(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 y;
 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 x;
 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 y;
 241        else if (xe < ye)
 242                return x;
 243
 244        /* Compare mantissa */
 245        if (xm < ym)
 246                return x;
 247        else if (xm > ym)
 248                return y;
 249        else if (xs == 1)
 250                return x;
 251        return y;
 252}
 253