linux/arch/mips/math-emu/sp_fdp.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/* IEEE754 floating point arithmetic
   3 * single precision
   4 */
   5/*
   6 * MIPS floating point support
   7 * Copyright (C) 1994-2000 Algorithmics Ltd.
   8 */
   9
  10#include "ieee754sp.h"
  11#include "ieee754dp.h"
  12
  13static inline union ieee754sp ieee754sp_nan_fdp(int xs, u64 xm)
  14{
  15        return buildsp(xs, SP_EMAX + 1 + SP_EBIAS,
  16                       xm >> (DP_FBITS - SP_FBITS));
  17}
  18
  19union ieee754sp ieee754sp_fdp(union ieee754dp x)
  20{
  21        union ieee754sp y;
  22        u32 rm;
  23
  24        COMPXDP;
  25        COMPYSP;
  26
  27        EXPLODEXDP;
  28
  29        ieee754_clearcx();
  30
  31        FLUSHXDP;
  32
  33        switch (xc) {
  34        case IEEE754_CLASS_SNAN:
  35                x = ieee754dp_nanxcpt(x);
  36                EXPLODEXDP;
  37                fallthrough;
  38        case IEEE754_CLASS_QNAN:
  39                y = ieee754sp_nan_fdp(xs, xm);
  40                if (!ieee754_csr.nan2008) {
  41                        EXPLODEYSP;
  42                        if (!ieee754_class_nan(yc))
  43                                y = ieee754sp_indef();
  44                }
  45                return y;
  46
  47        case IEEE754_CLASS_INF:
  48                return ieee754sp_inf(xs);
  49
  50        case IEEE754_CLASS_ZERO:
  51                return ieee754sp_zero(xs);
  52
  53        case IEEE754_CLASS_DNORM:
  54                /* can't possibly be sp representable */
  55                ieee754_setcx(IEEE754_UNDERFLOW);
  56                ieee754_setcx(IEEE754_INEXACT);
  57                if ((ieee754_csr.rm == FPU_CSR_RU && !xs) ||
  58                                (ieee754_csr.rm == FPU_CSR_RD && xs))
  59                        return ieee754sp_mind(xs);
  60                return ieee754sp_zero(xs);
  61
  62        case IEEE754_CLASS_NORM:
  63                break;
  64        }
  65
  66        /*
  67         * Convert from DP_FBITS to SP_FBITS+3 with sticky right shift.
  68         */
  69        rm = (xm >> (DP_FBITS - (SP_FBITS + 3))) |
  70             ((xm << (64 - (DP_FBITS - (SP_FBITS + 3)))) != 0);
  71
  72        return ieee754sp_format(xs, xe, rm);
  73}
  74