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

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

DEFINITIONS

This source file includes following definitions.
  1. ieee754sp_tlong

   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 s64 ieee754sp_tlong(union ieee754sp x)
  13 {
  14         u32 residue;
  15         int round;
  16         int sticky;
  17         int odd;
  18 
  19         COMPXDP;                /* <-- need 64-bit mantissa tmp */
  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 ieee754di_indef();
  31 
  32         case IEEE754_CLASS_INF:
  33                 ieee754_setcx(IEEE754_INVALID_OPERATION);
  34                 return ieee754di_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 >= 63) {
  44                 /* look for valid corner case */
  45                 if (xe == 63 && xs && xm == SP_HIDDEN_BIT)
  46                         return -0x8000000000000000LL;
  47                 /* Set invalid. We will only use overflow for floating
  48                    point overflow */
  49                 ieee754_setcx(IEEE754_INVALID_OPERATION);
  50                 return ieee754di_overflow(xs);
  51         }
  52         /* oh gawd */
  53         if (xe > SP_FBITS) {
  54                 xm <<= xe - SP_FBITS;
  55         } else if (xe < SP_FBITS) {
  56                 if (xe < -1) {
  57                         residue = xm;
  58                         round = 0;
  59                         sticky = residue != 0;
  60                         xm = 0;
  61                 } else {
  62                         residue = xm << (32 - SP_FBITS + xe);
  63                         round = (residue >> 31) != 0;
  64                         sticky = (residue << 1) != 0;
  65                         xm >>= SP_FBITS - xe;
  66                 }
  67                 odd = (xm & 0x1) != 0x0;
  68                 switch (ieee754_csr.rm) {
  69                 case FPU_CSR_RN:
  70                         if (round && (sticky || odd))
  71                                 xm++;
  72                         break;
  73                 case FPU_CSR_RZ:
  74                         break;
  75                 case FPU_CSR_RU:        /* toward +Infinity */
  76                         if ((round || sticky) && !xs)
  77                                 xm++;
  78                         break;
  79                 case FPU_CSR_RD:        /* toward -Infinity */
  80                         if ((round || sticky) && xs)
  81                                 xm++;
  82                         break;
  83                 }
  84                 if ((xm >> 63) != 0) {
  85                         /* This can happen after rounding */
  86                         ieee754_setcx(IEEE754_INVALID_OPERATION);
  87                         return ieee754di_overflow(xs);
  88                 }
  89                 if (round || sticky)
  90                         ieee754_setcx(IEEE754_INEXACT);
  91         }
  92         if (xs)
  93                 return -xm;
  94         else
  95                 return xm;
  96 }

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