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

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

DEFINITIONS

This source file includes following definitions.
  1. sgl_to_sgl_fcnvuf
  2. sgl_to_dbl_fcnvuf
  3. dbl_to_sgl_fcnvuf
  4. dbl_to_dbl_fcnvuf

   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/fcnvuf.c              $Revision: 1.1 $
  13  *
  14  *  Purpose:
  15  *      Fixed point to Floating-point Converts
  16  *
  17  *  External Interfaces:
  18  *      dbl_to_dbl_fcnvuf(srcptr,nullptr,dstptr,status)
  19  *      dbl_to_sgl_fcnvuf(srcptr,nullptr,dstptr,status)
  20  *      sgl_to_dbl_fcnvuf(srcptr,nullptr,dstptr,status)
  21  *      sgl_to_sgl_fcnvuf(srcptr,nullptr,dstptr,status)
  22  *
  23  *  Internal Interfaces:
  24  *
  25  *  Theory:
  26  *      <<please update with a overview of the operation of this file>>
  27  *
  28  * END_DESC
  29 */
  30 
  31 
  32 #include "float.h"
  33 #include "sgl_float.h"
  34 #include "dbl_float.h"
  35 #include "cnv_float.h"
  36 
  37 /************************************************************************
  38  *  Fixed point to Floating-point Converts                              *
  39  ************************************************************************/
  40 
  41 /*
  42  *  Convert Single Unsigned Fixed to Single Floating-point format
  43  */
  44 
  45 int
  46 sgl_to_sgl_fcnvuf(
  47                         unsigned int *srcptr,
  48                         unsigned int *nullptr,
  49                         sgl_floating_point *dstptr,
  50                         unsigned int *status)
  51 {
  52         register unsigned int src, result = 0;
  53         register int dst_exponent;
  54 
  55         src = *srcptr;
  56 
  57         /* Check for zero */ 
  58         if (src == 0) { 
  59                 Sgl_setzero(result); 
  60                 *dstptr = result;
  61                 return(NOEXCEPTION); 
  62         } 
  63         /*
  64          * Generate exponent and normalized mantissa
  65          */
  66         dst_exponent = 16;    /* initialize for normalization */
  67         /*
  68          * Check word for most significant bit set.  Returns
  69          * a value in dst_exponent indicating the bit position,
  70          * between -1 and 30.
  71          */
  72         Find_ms_one_bit(src,dst_exponent);
  73         /*  left justify source, with msb at bit position 0  */
  74         src <<= dst_exponent+1;
  75         Sgl_set_mantissa(result, src >> SGL_EXP_LENGTH);
  76         Sgl_set_exponent(result, 30+SGL_BIAS - dst_exponent);
  77 
  78         /* check for inexact */
  79         if (Suint_isinexact_to_sgl(src)) {
  80                 switch (Rounding_mode()) {
  81                         case ROUNDPLUS: 
  82                                 Sgl_increment(result);
  83                                 break;
  84                         case ROUNDMINUS: /* never negative */
  85                                 break;
  86                         case ROUNDNEAREST:
  87                                 Sgl_roundnearest_from_suint(src,result);
  88                                 break;
  89                 }
  90                 if (Is_inexacttrap_enabled()) {
  91                         *dstptr = result;
  92                         return(INEXACTEXCEPTION);
  93                 }
  94                 else Set_inexactflag();
  95         }
  96         *dstptr = result;
  97         return(NOEXCEPTION);
  98 }
  99 
 100 /*
 101  *  Single Unsigned Fixed to Double Floating-point 
 102  */
 103 
 104 int
 105 sgl_to_dbl_fcnvuf(
 106                         unsigned int *srcptr,
 107                         unsigned int *nullptr,
 108                         dbl_floating_point *dstptr,
 109                         unsigned int *status)
 110 {
 111         register int dst_exponent;
 112         register unsigned int src, resultp1 = 0, resultp2 = 0;
 113 
 114         src = *srcptr;
 115 
 116         /* Check for zero */
 117         if (src == 0) {
 118                 Dbl_setzero(resultp1,resultp2);
 119                 Dbl_copytoptr(resultp1,resultp2,dstptr);
 120                 return(NOEXCEPTION);
 121         }
 122         /*
 123          * Generate exponent and normalized mantissa
 124          */
 125         dst_exponent = 16;    /* initialize for normalization */
 126         /*
 127          * Check word for most significant bit set.  Returns
 128          * a value in dst_exponent indicating the bit position,
 129          * between -1 and 30.
 130          */
 131         Find_ms_one_bit(src,dst_exponent);
 132         /*  left justify source, with msb at bit position 0  */
 133         src <<= dst_exponent+1;
 134         Dbl_set_mantissap1(resultp1, src >> DBL_EXP_LENGTH);
 135         Dbl_set_mantissap2(resultp2, src << (32-DBL_EXP_LENGTH));
 136         Dbl_set_exponent(resultp1, (30+DBL_BIAS) - dst_exponent);
 137         Dbl_copytoptr(resultp1,resultp2,dstptr);
 138         return(NOEXCEPTION);
 139 }
 140 
 141 /*
 142  *  Double Unsigned Fixed to Single Floating-point 
 143  */
 144 
 145 int
 146 dbl_to_sgl_fcnvuf(
 147                         dbl_unsigned *srcptr,
 148                         unsigned int *nullptr,
 149                         sgl_floating_point *dstptr,
 150                         unsigned int *status)
 151 {
 152         int dst_exponent;
 153         unsigned int srcp1, srcp2, result = 0;
 154 
 155         Duint_copyfromptr(srcptr,srcp1,srcp2);
 156 
 157         /* Check for zero */
 158         if (srcp1 == 0 && srcp2 == 0) {
 159                 Sgl_setzero(result);
 160                 *dstptr = result;
 161                 return(NOEXCEPTION);
 162         }
 163         /*
 164          * Generate exponent and normalized mantissa
 165          */
 166         dst_exponent = 16;    /* initialize for normalization */
 167         if (srcp1 == 0) {
 168                 /*
 169                  * Check word for most significant bit set.  Returns
 170                  * a value in dst_exponent indicating the bit position,
 171                  * between -1 and 30.
 172                  */
 173                 Find_ms_one_bit(srcp2,dst_exponent);
 174                 /*  left justify source, with msb at bit position 0  */
 175                 srcp1 = srcp2 << dst_exponent+1;    
 176                 srcp2 = 0;
 177                 /*
 178                  *  since msb set is in second word, need to 
 179                  *  adjust bit position count
 180                  */
 181                 dst_exponent += 32;
 182         }
 183         else {
 184                 /*
 185                  * Check word for most significant bit set.  Returns
 186                  * a value in dst_exponent indicating the bit position,
 187                  * between -1 and 30.
 188                  *
 189                  */
 190                 Find_ms_one_bit(srcp1,dst_exponent);
 191                 /*  left justify source, with msb at bit position 0  */
 192                 if (dst_exponent >= 0) {
 193                         Variable_shift_double(srcp1,srcp2,(31-dst_exponent),
 194                          srcp1); 
 195                         srcp2 <<= dst_exponent+1;
 196                 }
 197         }
 198         Sgl_set_mantissa(result, srcp1 >> SGL_EXP_LENGTH);
 199         Sgl_set_exponent(result, (62+SGL_BIAS) - dst_exponent);
 200 
 201         /* check for inexact */
 202         if (Duint_isinexact_to_sgl(srcp1,srcp2)) {
 203                 switch (Rounding_mode()) {
 204                         case ROUNDPLUS: 
 205                                 Sgl_increment(result);
 206                                 break;
 207                         case ROUNDMINUS: /* never negative */
 208                                 break;
 209                         case ROUNDNEAREST:
 210                                 Sgl_roundnearest_from_duint(srcp1,srcp2,result);
 211                                 break;
 212                 }
 213                 if (Is_inexacttrap_enabled()) {
 214                         *dstptr = result;
 215                         return(INEXACTEXCEPTION);
 216                 }
 217                 else Set_inexactflag();
 218         }
 219         *dstptr = result;
 220         return(NOEXCEPTION);
 221 }
 222 
 223 /*
 224  *  Double Unsigned Fixed to Double Floating-point 
 225  */
 226 
 227 int
 228 dbl_to_dbl_fcnvuf(
 229                     dbl_unsigned *srcptr,
 230                     unsigned int *nullptr,
 231                     dbl_floating_point *dstptr,
 232                     unsigned int *status)
 233 {
 234         register int dst_exponent;
 235         register unsigned int srcp1, srcp2, resultp1 = 0, resultp2 = 0;
 236 
 237         Duint_copyfromptr(srcptr,srcp1,srcp2);
 238 
 239         /* Check for zero */
 240         if (srcp1 == 0 && srcp2 ==0) {
 241                 Dbl_setzero(resultp1,resultp2);
 242                 Dbl_copytoptr(resultp1,resultp2,dstptr);
 243                 return(NOEXCEPTION);
 244         }
 245         /*
 246          * Generate exponent and normalized mantissa
 247          */
 248         dst_exponent = 16;    /* initialize for normalization */
 249         if (srcp1 == 0) {
 250                 /*
 251                  * Check word for most significant bit set.  Returns
 252                  * a value in dst_exponent indicating the bit position,
 253                  * between -1 and 30.
 254                  */
 255                 Find_ms_one_bit(srcp2,dst_exponent);
 256                 /*  left justify source, with msb at bit position 0  */
 257                 srcp1 = srcp2 << dst_exponent+1;
 258                 srcp2 = 0;
 259                 /*
 260                  *  since msb set is in second word, need to 
 261                  *  adjust bit position count
 262                  */
 263                 dst_exponent += 32;
 264         }
 265         else {
 266                 /*
 267                  * Check word for most significant bit set.  Returns
 268                  * a value in dst_exponent indicating the bit position,
 269                  * between -1 and 30.
 270                  */
 271                 Find_ms_one_bit(srcp1,dst_exponent);
 272                 /*  left justify source, with msb at bit position 0  */
 273                 if (dst_exponent >= 0) {
 274                         Variable_shift_double(srcp1,srcp2,(31-dst_exponent),
 275                          srcp1); 
 276                         srcp2 <<= dst_exponent+1;
 277                 }
 278         }
 279         Dbl_set_mantissap1(resultp1, srcp1 >> DBL_EXP_LENGTH);
 280         Shiftdouble(srcp1,srcp2,DBL_EXP_LENGTH,resultp2);
 281         Dbl_set_exponent(resultp1, (62+DBL_BIAS) - dst_exponent);
 282 
 283         /* check for inexact */
 284         if (Duint_isinexact_to_dbl(srcp2)) {
 285                 switch (Rounding_mode()) {
 286                         case ROUNDPLUS: 
 287                                 Dbl_increment(resultp1,resultp2);
 288                                 break;
 289                         case ROUNDMINUS: /* never negative */
 290                                 break;
 291                         case ROUNDNEAREST:
 292                                 Dbl_roundnearest_from_duint(srcp2,resultp1,
 293                                 resultp2);
 294                                 break;
 295                 }
 296                 if (Is_inexacttrap_enabled()) {
 297                         Dbl_copytoptr(resultp1,resultp2,dstptr);
 298                         return(INEXACTEXCEPTION);
 299                 }
 300                 else Set_inexactflag();
 301         }
 302         Dbl_copytoptr(resultp1,resultp2,dstptr);
 303         return(NOEXCEPTION);
 304 }
 305 

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