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