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

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

DEFINITIONS

This source file includes following definitions.
  1. sgl_to_dbl_fcnvff
  2. dbl_to_sgl_fcnvff

   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  *  File:
  12  *      @(#)    pa/spmath/fcnvff.c              $Revision: 1.1 $
  13  *
  14  *  Purpose:
  15  *      Single Floating-point to Double Floating-point
  16  *      Double Floating-point to Single Floating-point
  17  *
  18  *  External Interfaces:
  19  *      dbl_to_sgl_fcnvff(srcptr,nullptr,dstptr,status)
  20  *      sgl_to_dbl_fcnvff(srcptr,nullptr,dstptr,status)
  21  *
  22  *  Internal Interfaces:
  23  *
  24  *  Theory:
  25  *      <<please update with a overview of the operation of this file>>
  26  *
  27  * END_DESC
  28 */
  29 
  30 
  31 #include "float.h"
  32 #include "sgl_float.h"
  33 #include "dbl_float.h"
  34 #include "cnv_float.h"
  35 
  36 /*
  37  *  Single Floating-point to Double Floating-point 
  38  */
  39 /*ARGSUSED*/
  40 int
  41 sgl_to_dbl_fcnvff(
  42             sgl_floating_point *srcptr,
  43             unsigned int *nullptr,
  44             dbl_floating_point *dstptr,
  45             unsigned int *status)
  46 {
  47         register unsigned int src, resultp1, resultp2;
  48         register int src_exponent;
  49 
  50         src = *srcptr;
  51         src_exponent = Sgl_exponent(src);
  52         Dbl_allp1(resultp1) = Sgl_all(src);  /* set sign of result */
  53         /* 
  54          * Test for NaN or infinity
  55          */
  56         if (src_exponent == SGL_INFINITY_EXPONENT) {
  57                 /*
  58                  * determine if NaN or infinity
  59                  */
  60                 if (Sgl_iszero_mantissa(src)) {
  61                         /*
  62                          * is infinity; want to return double infinity
  63                          */
  64                         Dbl_setinfinity_exponentmantissa(resultp1,resultp2);
  65                         Dbl_copytoptr(resultp1,resultp2,dstptr);
  66                         return(NOEXCEPTION);
  67                 }
  68                 else {
  69                         /* 
  70                          * is NaN; signaling or quiet?
  71                          */
  72                         if (Sgl_isone_signaling(src)) {
  73                                 /* trap if INVALIDTRAP enabled */
  74                                 if (Is_invalidtrap_enabled())
  75                                         return(INVALIDEXCEPTION);
  76                                 /* make NaN quiet */
  77                                 else {
  78                                         Set_invalidflag();
  79                                         Sgl_set_quiet(src);
  80                                 }
  81                         }
  82                         /* 
  83                          * NaN is quiet, return as double NaN 
  84                          */
  85                         Dbl_setinfinity_exponent(resultp1);
  86                         Sgl_to_dbl_mantissa(src,resultp1,resultp2);
  87                         Dbl_copytoptr(resultp1,resultp2,dstptr);
  88                         return(NOEXCEPTION);
  89                 }
  90         }
  91         /* 
  92          * Test for zero or denormalized
  93          */
  94         if (src_exponent == 0) {
  95                 /*
  96                  * determine if zero or denormalized
  97                  */
  98                 if (Sgl_isnotzero_mantissa(src)) {
  99                         /*
 100                          * is denormalized; want to normalize
 101                          */
 102                         Sgl_clear_signexponent(src);
 103                         Sgl_leftshiftby1(src);
 104                         Sgl_normalize(src,src_exponent);
 105                         Sgl_to_dbl_exponent(src_exponent,resultp1);
 106                         Sgl_to_dbl_mantissa(src,resultp1,resultp2);
 107                 }
 108                 else {
 109                         Dbl_setzero_exponentmantissa(resultp1,resultp2);
 110                 }
 111                 Dbl_copytoptr(resultp1,resultp2,dstptr);
 112                 return(NOEXCEPTION);
 113         }
 114         /*
 115          * No special cases, just complete the conversion
 116          */
 117         Sgl_to_dbl_exponent(src_exponent, resultp1);
 118         Sgl_to_dbl_mantissa(Sgl_mantissa(src), resultp1,resultp2);
 119         Dbl_copytoptr(resultp1,resultp2,dstptr);
 120         return(NOEXCEPTION);
 121 }
 122 
 123 /*
 124  *  Double Floating-point to Single Floating-point 
 125  */
 126 /*ARGSUSED*/
 127 int
 128 dbl_to_sgl_fcnvff(
 129                     dbl_floating_point *srcptr,
 130                     unsigned int *nullptr,
 131                     sgl_floating_point *dstptr,
 132                     unsigned int *status)
 133 {
 134         register unsigned int srcp1, srcp2, result;
 135         register int src_exponent, dest_exponent, dest_mantissa;
 136         register boolean inexact = FALSE, guardbit = FALSE, stickybit = FALSE;
 137         register boolean lsb_odd = FALSE;
 138         boolean is_tiny = FALSE;
 139 
 140         Dbl_copyfromptr(srcptr,srcp1,srcp2);
 141         src_exponent = Dbl_exponent(srcp1);
 142         Sgl_all(result) = Dbl_allp1(srcp1);  /* set sign of result */
 143         /* 
 144          * Test for NaN or infinity
 145          */
 146         if (src_exponent == DBL_INFINITY_EXPONENT) {
 147                 /*
 148                  * determine if NaN or infinity
 149                  */
 150                 if (Dbl_iszero_mantissa(srcp1,srcp2)) {
 151                         /*
 152                          * is infinity; want to return single infinity
 153                          */
 154                         Sgl_setinfinity_exponentmantissa(result);
 155                         *dstptr = result;
 156                         return(NOEXCEPTION);
 157                 }
 158                 /* 
 159                  * is NaN; signaling or quiet?
 160                  */
 161                 if (Dbl_isone_signaling(srcp1)) {
 162                         /* trap if INVALIDTRAP enabled */
 163                         if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
 164                         else {
 165                                 Set_invalidflag();
 166                                 /* make NaN quiet */
 167                                 Dbl_set_quiet(srcp1);
 168                         }
 169                 }
 170                 /* 
 171                  * NaN is quiet, return as single NaN 
 172                  */
 173                 Sgl_setinfinity_exponent(result);
 174                 Sgl_set_mantissa(result,Dallp1(srcp1)<<3 | Dallp2(srcp2)>>29);
 175                 if (Sgl_iszero_mantissa(result)) Sgl_set_quiet(result);
 176                 *dstptr = result;
 177                 return(NOEXCEPTION);
 178         }
 179         /*
 180          * Generate result
 181          */
 182         Dbl_to_sgl_exponent(src_exponent,dest_exponent);
 183         if (dest_exponent > 0) {
 184                 Dbl_to_sgl_mantissa(srcp1,srcp2,dest_mantissa,inexact,guardbit, 
 185                 stickybit,lsb_odd);
 186         }
 187         else {
 188                 if (Dbl_iszero_exponentmantissa(srcp1,srcp2)){
 189                         Sgl_setzero_exponentmantissa(result);
 190                         *dstptr = result;
 191                         return(NOEXCEPTION);
 192                 }
 193                 if (Is_underflowtrap_enabled()) {
 194                         Dbl_to_sgl_mantissa(srcp1,srcp2,dest_mantissa,inexact,
 195                         guardbit,stickybit,lsb_odd);
 196                 }
 197                 else {
 198                         /* compute result, determine inexact info,
 199                          * and set Underflowflag if appropriate
 200                          */
 201                         Dbl_to_sgl_denormalized(srcp1,srcp2,dest_exponent,
 202                         dest_mantissa,inexact,guardbit,stickybit,lsb_odd,
 203                         is_tiny);
 204                 }
 205         }
 206         /* 
 207          * Now round result if not exact
 208          */
 209         if (inexact) {
 210                 switch (Rounding_mode()) {
 211                         case ROUNDPLUS: 
 212                                 if (Sgl_iszero_sign(result)) dest_mantissa++;
 213                                 break;
 214                         case ROUNDMINUS: 
 215                                 if (Sgl_isone_sign(result)) dest_mantissa++;
 216                                 break;
 217                         case ROUNDNEAREST:
 218                                 if (guardbit) {
 219                                    if (stickybit || lsb_odd) dest_mantissa++;
 220                                    }
 221                 }
 222         }
 223         Sgl_set_exponentmantissa(result,dest_mantissa);
 224 
 225         /*
 226          * check for mantissa overflow after rounding
 227          */
 228         if ((dest_exponent>0 || Is_underflowtrap_enabled()) && 
 229             Sgl_isone_hidden(result)) dest_exponent++;
 230 
 231         /* 
 232          * Test for overflow
 233          */
 234         if (dest_exponent >= SGL_INFINITY_EXPONENT) {
 235                 /* trap if OVERFLOWTRAP enabled */
 236                 if (Is_overflowtrap_enabled()) {
 237                         /* 
 238                          * Check for gross overflow
 239                          */
 240                         if (dest_exponent >= SGL_INFINITY_EXPONENT+SGL_WRAP) 
 241                                 return(UNIMPLEMENTEDEXCEPTION);
 242                         
 243                         /*
 244                          * Adjust bias of result
 245                          */
 246                         Sgl_setwrapped_exponent(result,dest_exponent,ovfl);
 247                         *dstptr = result;
 248                         if (inexact) 
 249                             if (Is_inexacttrap_enabled())
 250                                 return(OVERFLOWEXCEPTION|INEXACTEXCEPTION);
 251                             else Set_inexactflag();
 252                         return(OVERFLOWEXCEPTION);
 253                 }
 254                 Set_overflowflag();
 255                 inexact = TRUE;
 256                 /* set result to infinity or largest number */
 257                 Sgl_setoverflow(result);
 258         }
 259         /* 
 260          * Test for underflow
 261          */
 262         else if (dest_exponent <= 0) {
 263                 /* trap if UNDERFLOWTRAP enabled */
 264                 if (Is_underflowtrap_enabled()) {
 265                         /* 
 266                          * Check for gross underflow
 267                          */
 268                         if (dest_exponent <= -(SGL_WRAP))
 269                                 return(UNIMPLEMENTEDEXCEPTION);
 270                         /*
 271                          * Adjust bias of result
 272                          */
 273                         Sgl_setwrapped_exponent(result,dest_exponent,unfl);
 274                         *dstptr = result;
 275                         if (inexact) 
 276                             if (Is_inexacttrap_enabled())
 277                                 return(UNDERFLOWEXCEPTION|INEXACTEXCEPTION);
 278                             else Set_inexactflag();
 279                         return(UNDERFLOWEXCEPTION);
 280                 }
 281                  /* 
 282                   * result is denormalized or signed zero
 283                   */
 284                if (inexact && is_tiny) Set_underflowflag();
 285 
 286         }
 287         else Sgl_set_exponent(result,dest_exponent);
 288         *dstptr = result;
 289         /* 
 290          * Trap if inexact trap is enabled
 291          */
 292         if (inexact)
 293                 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
 294                 else Set_inexactflag();
 295         return(NOEXCEPTION);
 296 }

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