root/arch/parisc/math-emu/frnd.c

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

DEFINITIONS

This source file includes following definitions.
  1. sgl_frnd
  2. dbl_frnd

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Linux/PA-RISC Project (http://www.parisc-linux.org/)
   4  *
   5  * Floating-point emulation code
   6  *  Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
   7  */
   8 /*
   9  * BEGIN_DESC
  10  *
  11  *  Purpose:
  12  *      Single Floating-point Round to Integer
  13  *      Double Floating-point Round to Integer
  14  *      Quad Floating-point Round to Integer (returns unimplemented)
  15  *
  16  *  External Interfaces:
  17  *      dbl_frnd(srcptr,nullptr,dstptr,status)
  18  *      sgl_frnd(srcptr,nullptr,dstptr,status)
  19  *
  20  * END_DESC
  21 */
  22 
  23 
  24 #include "float.h"
  25 #include "sgl_float.h"
  26 #include "dbl_float.h"
  27 #include "cnv_float.h"
  28 
  29 /*
  30  *  Single Floating-point Round to Integer
  31  */
  32 
  33 /*ARGSUSED*/
  34 int
  35 sgl_frnd(sgl_floating_point *srcptr,
  36         unsigned int *nullptr,
  37         sgl_floating_point *dstptr,
  38         unsigned int *status)
  39 {
  40         register unsigned int src, result;
  41         register int src_exponent;
  42         register boolean inexact = FALSE;
  43 
  44         src = *srcptr;
  45         /*
  46          * check source operand for NaN or infinity
  47          */
  48         if ((src_exponent = Sgl_exponent(src)) == SGL_INFINITY_EXPONENT) {
  49                 /*
  50                  * is signaling NaN?
  51                  */
  52                 if (Sgl_isone_signaling(src)) {
  53                         /* trap if INVALIDTRAP enabled */
  54                         if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
  55                         /* make NaN quiet */
  56                         Set_invalidflag();
  57                         Sgl_set_quiet(src);
  58                 }
  59                 /*
  60                  * return quiet NaN or infinity
  61                  */
  62                 *dstptr = src;
  63                 return(NOEXCEPTION);
  64         }
  65         /* 
  66          * Need to round?
  67          */
  68         if ((src_exponent -= SGL_BIAS) >= SGL_P - 1) {
  69                 *dstptr = src;
  70                 return(NOEXCEPTION);
  71         }
  72         /*
  73          * Generate result
  74          */
  75         if (src_exponent >= 0) {
  76                 Sgl_clear_exponent_set_hidden(src);
  77                 result = src;
  78                 Sgl_rightshift(result,(SGL_P-1) - (src_exponent));
  79                 /* check for inexact */
  80                 if (Sgl_isinexact_to_fix(src,src_exponent)) {
  81                         inexact = TRUE;
  82                         /*  round result  */
  83                         switch (Rounding_mode()) {
  84                         case ROUNDPLUS:
  85                              if (Sgl_iszero_sign(src)) Sgl_increment(result);
  86                              break;
  87                         case ROUNDMINUS:
  88                              if (Sgl_isone_sign(src)) Sgl_increment(result);
  89                              break;
  90                         case ROUNDNEAREST:
  91                              if (Sgl_isone_roundbit(src,src_exponent))
  92                                 if (Sgl_isone_stickybit(src,src_exponent) 
  93                                 || (Sgl_isone_lowmantissa(result))) 
  94                                         Sgl_increment(result);
  95                         } 
  96                 }
  97                 Sgl_leftshift(result,(SGL_P-1) - (src_exponent));
  98                 if (Sgl_isone_hiddenoverflow(result)) 
  99                         Sgl_set_exponent(result,src_exponent + (SGL_BIAS+1));
 100                 else Sgl_set_exponent(result,src_exponent + SGL_BIAS);
 101         }
 102         else {
 103                 result = src;           /* set sign */
 104                 Sgl_setzero_exponentmantissa(result);
 105                 /* check for inexact */
 106                 if (Sgl_isnotzero_exponentmantissa(src)) {
 107                         inexact = TRUE;
 108                         /*  round result  */
 109                         switch (Rounding_mode()) {
 110                         case ROUNDPLUS:
 111                              if (Sgl_iszero_sign(src)) 
 112                                 Sgl_set_exponent(result,SGL_BIAS);
 113                              break;
 114                         case ROUNDMINUS:
 115                              if (Sgl_isone_sign(src)) 
 116                                 Sgl_set_exponent(result,SGL_BIAS);
 117                              break;
 118                         case ROUNDNEAREST:
 119                              if (src_exponent == -1)
 120                                 if (Sgl_isnotzero_mantissa(src))
 121                                    Sgl_set_exponent(result,SGL_BIAS);
 122                         } 
 123                 }
 124         }
 125         *dstptr = result;
 126         if (inexact) {
 127                 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
 128                 else Set_inexactflag();
 129         }
 130         return(NOEXCEPTION);
 131 } 
 132 
 133 /*
 134  *  Double Floating-point Round to Integer
 135  */
 136 
 137 /*ARGSUSED*/
 138 int
 139 dbl_frnd(
 140         dbl_floating_point *srcptr,
 141         unsigned int *nullptr,
 142         dbl_floating_point *dstptr,
 143         unsigned int *status)
 144 {
 145         register unsigned int srcp1, srcp2, resultp1, resultp2;
 146         register int src_exponent;
 147         register boolean inexact = FALSE;
 148 
 149         Dbl_copyfromptr(srcptr,srcp1,srcp2);
 150         /*
 151          * check source operand for NaN or infinity
 152          */
 153         if ((src_exponent = Dbl_exponent(srcp1)) == DBL_INFINITY_EXPONENT) {
 154                 /*
 155                  * is signaling NaN?
 156                  */
 157                 if (Dbl_isone_signaling(srcp1)) {
 158                         /* trap if INVALIDTRAP enabled */
 159                         if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
 160                         /* make NaN quiet */
 161                         Set_invalidflag();
 162                         Dbl_set_quiet(srcp1);
 163                 }
 164                 /*
 165                  * return quiet NaN or infinity
 166                  */
 167                 Dbl_copytoptr(srcp1,srcp2,dstptr);
 168                 return(NOEXCEPTION);
 169         }
 170         /* 
 171          * Need to round?
 172          */
 173         if ((src_exponent -= DBL_BIAS) >= DBL_P - 1) {
 174                 Dbl_copytoptr(srcp1,srcp2,dstptr);
 175                 return(NOEXCEPTION);
 176         }
 177         /*
 178          * Generate result
 179          */
 180         if (src_exponent >= 0) {
 181                 Dbl_clear_exponent_set_hidden(srcp1);
 182                 resultp1 = srcp1;
 183                 resultp2 = srcp2;
 184                 Dbl_rightshift(resultp1,resultp2,(DBL_P-1) - (src_exponent));
 185                 /* check for inexact */
 186                 if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
 187                         inexact = TRUE;
 188                         /*  round result  */
 189                         switch (Rounding_mode()) {
 190                         case ROUNDPLUS:
 191                              if (Dbl_iszero_sign(srcp1)) 
 192                                 Dbl_increment(resultp1,resultp2);
 193                              break;
 194                         case ROUNDMINUS:
 195                              if (Dbl_isone_sign(srcp1)) 
 196                                 Dbl_increment(resultp1,resultp2);
 197                              break;
 198                         case ROUNDNEAREST:
 199                              if (Dbl_isone_roundbit(srcp1,srcp2,src_exponent))
 200                               if (Dbl_isone_stickybit(srcp1,srcp2,src_exponent) 
 201                                   || (Dbl_isone_lowmantissap2(resultp2))) 
 202                                         Dbl_increment(resultp1,resultp2);
 203                         } 
 204                 }
 205                 Dbl_leftshift(resultp1,resultp2,(DBL_P-1) - (src_exponent));
 206                 if (Dbl_isone_hiddenoverflow(resultp1))
 207                         Dbl_set_exponent(resultp1,src_exponent + (DBL_BIAS+1));
 208                 else Dbl_set_exponent(resultp1,src_exponent + DBL_BIAS);
 209         }
 210         else {
 211                 resultp1 = srcp1;  /* set sign */
 212                 Dbl_setzero_exponentmantissa(resultp1,resultp2);
 213                 /* check for inexact */
 214                 if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
 215                         inexact = TRUE;
 216                         /*  round result  */
 217                         switch (Rounding_mode()) {
 218                         case ROUNDPLUS:
 219                              if (Dbl_iszero_sign(srcp1)) 
 220                                 Dbl_set_exponent(resultp1,DBL_BIAS);
 221                              break;
 222                         case ROUNDMINUS:
 223                              if (Dbl_isone_sign(srcp1)) 
 224                                 Dbl_set_exponent(resultp1,DBL_BIAS);
 225                              break;
 226                         case ROUNDNEAREST:
 227                              if (src_exponent == -1)
 228                                 if (Dbl_isnotzero_mantissa(srcp1,srcp2))
 229                                    Dbl_set_exponent(resultp1,DBL_BIAS);
 230                         } 
 231                 }
 232         }
 233         Dbl_copytoptr(resultp1,resultp2,dstptr);
 234         if (inexact) {
 235                 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
 236                 else Set_inexactflag();
 237         }
 238         return(NOEXCEPTION);
 239 }

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