root/arch/mips/math-emu/sp_tint.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ieee754sp_tint

   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 
  12 int ieee754sp_tint(union ieee754sp x)
  13 {
  14         u32 residue;
  15         int round;
  16         int sticky;
  17         int odd;
  18 
  19         COMPXSP;
  20 
  21         ieee754_clearcx();
  22 
  23         EXPLODEXSP;
  24         FLUSHXSP;
  25 
  26         switch (xc) {
  27         case IEEE754_CLASS_SNAN:
  28         case IEEE754_CLASS_QNAN:
  29                 ieee754_setcx(IEEE754_INVALID_OPERATION);
  30                 return ieee754si_indef();
  31 
  32         case IEEE754_CLASS_INF:
  33                 ieee754_setcx(IEEE754_INVALID_OPERATION);
  34                 return ieee754si_overflow(xs);
  35 
  36         case IEEE754_CLASS_ZERO:
  37                 return 0;
  38 
  39         case IEEE754_CLASS_DNORM:
  40         case IEEE754_CLASS_NORM:
  41                 break;
  42         }
  43         if (xe >= 31) {
  44                 /* look for valid corner case */
  45                 if (xe == 31 && xs && xm == SP_HIDDEN_BIT)
  46                         return -0x80000000;
  47                 /* Set invalid. We will only use overflow for floating
  48                    point overflow */
  49                 ieee754_setcx(IEEE754_INVALID_OPERATION);
  50                 return ieee754si_overflow(xs);
  51         }
  52         /* oh gawd */
  53         if (xe > SP_FBITS) {
  54                 xm <<= xe - SP_FBITS;
  55         } else {
  56                 if (xe < -1) {
  57                         residue = xm;
  58                         round = 0;
  59                         sticky = residue != 0;
  60                         xm = 0;
  61                 } else {
  62                         /* Shifting a u32 32 times does not work,
  63                         * so we do it in two steps. Be aware that xe
  64                         * may be -1 */
  65                         residue = xm << (xe + 1);
  66                         residue <<= 31 - SP_FBITS;
  67                         round = (residue >> 31) != 0;
  68                         sticky = (residue << 1) != 0;
  69                         xm >>= SP_FBITS - xe;
  70                 }
  71                 odd = (xm & 0x1) != 0x0;
  72                 switch (ieee754_csr.rm) {
  73                 case FPU_CSR_RN:
  74                         if (round && (sticky || odd))
  75                                 xm++;
  76                         break;
  77                 case FPU_CSR_RZ:
  78                         break;
  79                 case FPU_CSR_RU:        /* toward +Infinity */
  80                         if ((round || sticky) && !xs)
  81                                 xm++;
  82                         break;
  83                 case FPU_CSR_RD:        /* toward -Infinity */
  84                         if ((round || sticky) && xs)
  85                                 xm++;
  86                         break;
  87                 }
  88                 if ((xm >> 31) != 0) {
  89                         /* This can happen after rounding */
  90                         ieee754_setcx(IEEE754_INVALID_OPERATION);
  91                         return ieee754si_overflow(xs);
  92                 }
  93                 if (round || sticky)
  94                         ieee754_setcx(IEEE754_INEXACT);
  95         }
  96         if (xs)
  97                 return -xm;
  98         else
  99                 return xm;
 100 }

/* [<][>][^][v][top][bottom][index][help] */