linux/arch/mips/math-emu/sp_rint.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 * Copyright (C) 2017 Imagination Technologies, Ltd.
   9 * Author: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
  10 */
  11
  12#include "ieee754sp.h"
  13
  14union ieee754sp ieee754sp_rint(union ieee754sp x)
  15{
  16        union ieee754sp ret;
  17        u32 residue;
  18        int sticky;
  19        int round;
  20        int odd;
  21
  22        COMPXDP;                /* <-- DP needed for 64-bit mantissa tmp */
  23
  24        ieee754_clearcx();
  25
  26        EXPLODEXSP;
  27        FLUSHXSP;
  28
  29        if (xc == IEEE754_CLASS_SNAN)
  30                return ieee754sp_nanxcpt(x);
  31
  32        if ((xc == IEEE754_CLASS_QNAN) ||
  33            (xc == IEEE754_CLASS_INF) ||
  34            (xc == IEEE754_CLASS_ZERO))
  35                return x;
  36
  37        if (xe >= SP_FBITS)
  38                return x;
  39
  40        if (xe < -1) {
  41                residue = xm;
  42                round = 0;
  43                sticky = residue != 0;
  44                xm = 0;
  45        } else {
  46                residue = xm << (xe + 1);
  47                residue <<= 31 - SP_FBITS;
  48                round = (residue >> 31) != 0;
  49                sticky = (residue << 1) != 0;
  50                xm >>= SP_FBITS - xe;
  51        }
  52
  53        odd = (xm & 0x1) != 0x0;
  54
  55        switch (ieee754_csr.rm) {
  56        case FPU_CSR_RN:        /* toward nearest */
  57                if (round && (sticky || odd))
  58                        xm++;
  59                break;
  60        case FPU_CSR_RZ:        /* toward zero */
  61                break;
  62        case FPU_CSR_RU:        /* toward +infinity */
  63                if ((round || sticky) && !xs)
  64                        xm++;
  65                break;
  66        case FPU_CSR_RD:        /* toward -infinity */
  67                if ((round || sticky) && xs)
  68                        xm++;
  69                break;
  70        }
  71
  72        if (round || sticky)
  73                ieee754_setcx(IEEE754_INEXACT);
  74
  75        ret = ieee754sp_flong(xm);
  76        SPSIGN(ret) = xs;
  77
  78        return ret;
  79}
  80