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

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

DEFINITIONS

This source file includes following definitions.
  1. sgl_to_sgl_fcnvxf
  2. sgl_to_dbl_fcnvxf
  3. dbl_to_sgl_fcnvxf
  4. dbl_to_dbl_fcnvxf

   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/fcnvxf.c              $Revision: 1.1 $
  13  *
  14  *  Purpose:
  15  *      Single Fixed-point to Single Floating-point
  16  *      Single Fixed-point to Double Floating-point 
  17  *      Double Fixed-point to Single Floating-point 
  18  *      Double Fixed-point to Double Floating-point 
  19  *
  20  *  External Interfaces:
  21  *      dbl_to_dbl_fcnvxf(srcptr,nullptr,dstptr,status)
  22  *      dbl_to_sgl_fcnvxf(srcptr,nullptr,dstptr,status)
  23  *      sgl_to_dbl_fcnvxf(srcptr,nullptr,dstptr,status)
  24  *      sgl_to_sgl_fcnvxf(srcptr,nullptr,dstptr,status)
  25  *
  26  *  Internal Interfaces:
  27  *
  28  *  Theory:
  29  *      <<please update with a overview of the operation of this file>>
  30  *
  31  * END_DESC
  32 */
  33 
  34 
  35 #include "float.h"
  36 #include "sgl_float.h"
  37 #include "dbl_float.h"
  38 #include "cnv_float.h"
  39 
  40 /*
  41  *  Convert single fixed-point to single floating-point format
  42  */
  43 
  44 int
  45 sgl_to_sgl_fcnvxf(
  46                     int *srcptr,
  47                     unsigned int *nullptr,
  48                     sgl_floating_point *dstptr,
  49                     unsigned int *status)
  50 {
  51         register int src, dst_exponent;
  52         register unsigned int result = 0;
  53 
  54         src = *srcptr;
  55         /* 
  56          * set sign bit of result and get magnitude of source 
  57          */
  58         if (src < 0) {
  59                 Sgl_setone_sign(result);  
  60                 Int_negate(src);
  61         }
  62         else {
  63                 Sgl_setzero_sign(result);
  64                 /* Check for zero */ 
  65                 if (src == 0) { 
  66                         Sgl_setzero(result); 
  67                         *dstptr = result;
  68                         return(NOEXCEPTION); 
  69                 } 
  70         }
  71         /*
  72          * Generate exponent and normalized mantissa
  73          */
  74         dst_exponent = 16;    /* initialize for normalization */
  75         /*
  76          * Check word for most significant bit set.  Returns
  77          * a value in dst_exponent indicating the bit position,
  78          * between -1 and 30.
  79          */
  80         Find_ms_one_bit(src,dst_exponent);
  81         /*  left justify source, with msb at bit position 1  */
  82         if (dst_exponent >= 0) src <<= dst_exponent;
  83         else src = 1 << 30;
  84         Sgl_set_mantissa(result, src >> (SGL_EXP_LENGTH-1));
  85         Sgl_set_exponent(result, 30+SGL_BIAS - dst_exponent);
  86 
  87         /* check for inexact */
  88         if (Int_isinexact_to_sgl(src)) {
  89                 switch (Rounding_mode()) {
  90                         case ROUNDPLUS: 
  91                                 if (Sgl_iszero_sign(result)) 
  92                                         Sgl_increment(result);
  93                                 break;
  94                         case ROUNDMINUS: 
  95                                 if (Sgl_isone_sign(result)) 
  96                                         Sgl_increment(result);
  97                                 break;
  98                         case ROUNDNEAREST:
  99                                 Sgl_roundnearest_from_int(src,result);
 100                 }
 101                 if (Is_inexacttrap_enabled()) {
 102                         *dstptr = result;
 103                         return(INEXACTEXCEPTION);
 104                 }
 105                 else Set_inexactflag();
 106         }
 107         *dstptr = result;
 108         return(NOEXCEPTION);
 109 }
 110 
 111 /*
 112  *  Single Fixed-point to Double Floating-point 
 113  */
 114 
 115 int
 116 sgl_to_dbl_fcnvxf(
 117                     int *srcptr,
 118                     unsigned int *nullptr,
 119                     dbl_floating_point *dstptr,
 120                     unsigned int *status)
 121 {
 122         register int src, dst_exponent;
 123         register unsigned int resultp1 = 0, resultp2 = 0;
 124 
 125         src = *srcptr;
 126         /* 
 127          * set sign bit of result and get magnitude of source 
 128          */
 129         if (src < 0) {
 130                 Dbl_setone_sign(resultp1);  
 131                 Int_negate(src);
 132         }
 133         else {
 134                 Dbl_setzero_sign(resultp1);
 135                 /* Check for zero */
 136                 if (src == 0) {
 137                         Dbl_setzero(resultp1,resultp2);
 138                         Dbl_copytoptr(resultp1,resultp2,dstptr);
 139                         return(NOEXCEPTION);
 140                 }
 141         }
 142         /*
 143          * Generate exponent and normalized mantissa
 144          */
 145         dst_exponent = 16;    /* initialize for normalization */
 146         /*
 147          * Check word for most significant bit set.  Returns
 148          * a value in dst_exponent indicating the bit position,
 149          * between -1 and 30.
 150          */
 151         Find_ms_one_bit(src,dst_exponent);
 152         /*  left justify source, with msb at bit position 1  */
 153         if (dst_exponent >= 0) src <<= dst_exponent;
 154         else src = 1 << 30;
 155         Dbl_set_mantissap1(resultp1, src >> DBL_EXP_LENGTH - 1);
 156         Dbl_set_mantissap2(resultp2, src << (33-DBL_EXP_LENGTH));
 157         Dbl_set_exponent(resultp1, (30+DBL_BIAS) - dst_exponent);
 158         Dbl_copytoptr(resultp1,resultp2,dstptr);
 159         return(NOEXCEPTION);
 160 }
 161 
 162 /*
 163  *  Double Fixed-point to Single Floating-point 
 164  */
 165 
 166 int
 167 dbl_to_sgl_fcnvxf(
 168                         dbl_integer *srcptr,
 169                         unsigned int *nullptr,
 170                         sgl_floating_point *dstptr,
 171                         unsigned int *status)
 172 {
 173         int dst_exponent, srcp1;
 174         unsigned int result = 0, srcp2;
 175 
 176         Dint_copyfromptr(srcptr,srcp1,srcp2);
 177         /* 
 178          * set sign bit of result and get magnitude of source 
 179          */
 180         if (srcp1 < 0) {
 181                 Sgl_setone_sign(result);  
 182                 Dint_negate(srcp1,srcp2);
 183         }
 184         else {
 185                 Sgl_setzero_sign(result);
 186                 /* Check for zero */
 187                 if (srcp1 == 0 && srcp2 == 0) {
 188                         Sgl_setzero(result);
 189                         *dstptr = result;
 190                         return(NOEXCEPTION);
 191                 }
 192         }
 193         /*
 194          * Generate exponent and normalized mantissa
 195          */
 196         dst_exponent = 16;    /* initialize for normalization */
 197         if (srcp1 == 0) {
 198                 /*
 199                  * Check word for most significant bit set.  Returns
 200                  * a value in dst_exponent indicating the bit position,
 201                  * between -1 and 30.
 202                  */
 203                 Find_ms_one_bit(srcp2,dst_exponent);
 204                 /*  left justify source, with msb at bit position 1  */
 205                 if (dst_exponent >= 0) {
 206                         srcp1 = srcp2 << dst_exponent;    
 207                         srcp2 = 0;
 208                 }
 209                 else {
 210                         srcp1 = srcp2 >> 1;
 211                         srcp2 <<= 31; 
 212                 }
 213                 /*
 214                  *  since msb set is in second word, need to 
 215                  *  adjust bit position count
 216                  */
 217                 dst_exponent += 32;
 218         }
 219         else {
 220                 /*
 221                  * Check word for most significant bit set.  Returns
 222                  * a value in dst_exponent indicating the bit position,
 223                  * between -1 and 30.
 224                  *
 225                  */
 226                 Find_ms_one_bit(srcp1,dst_exponent);
 227                 /*  left justify source, with msb at bit position 1  */
 228                 if (dst_exponent > 0) {
 229                         Variable_shift_double(srcp1,srcp2,(32-dst_exponent),
 230                          srcp1); 
 231                         srcp2 <<= dst_exponent;
 232                 }
 233                 /*
 234                  * If dst_exponent = 0, we don't need to shift anything.
 235                  * If dst_exponent = -1, src = - 2**63 so we won't need to 
 236                  * shift srcp2.
 237                  */
 238                 else srcp1 >>= -(dst_exponent);
 239         }
 240         Sgl_set_mantissa(result, srcp1 >> SGL_EXP_LENGTH - 1);
 241         Sgl_set_exponent(result, (62+SGL_BIAS) - dst_exponent);
 242 
 243         /* check for inexact */
 244         if (Dint_isinexact_to_sgl(srcp1,srcp2)) {
 245                 switch (Rounding_mode()) {
 246                         case ROUNDPLUS: 
 247                                 if (Sgl_iszero_sign(result)) 
 248                                         Sgl_increment(result);
 249                                 break;
 250                         case ROUNDMINUS: 
 251                                 if (Sgl_isone_sign(result)) 
 252                                         Sgl_increment(result);
 253                                 break;
 254                         case ROUNDNEAREST:
 255                                 Sgl_roundnearest_from_dint(srcp1,srcp2,result);
 256                 }
 257                 if (Is_inexacttrap_enabled()) {
 258                         *dstptr = result;
 259                         return(INEXACTEXCEPTION);
 260                 }
 261                 else Set_inexactflag();
 262         }
 263         *dstptr = result;
 264         return(NOEXCEPTION);
 265 }
 266 
 267 /*
 268  *  Double Fixed-point to Double Floating-point 
 269  */
 270 
 271 int
 272 dbl_to_dbl_fcnvxf(
 273                     dbl_integer *srcptr,
 274                     unsigned int *nullptr,
 275                     dbl_floating_point *dstptr,
 276                     unsigned int *status)
 277 {
 278         register int srcp1, dst_exponent;
 279         register unsigned int srcp2, resultp1 = 0, resultp2 = 0;
 280 
 281         Dint_copyfromptr(srcptr,srcp1,srcp2);
 282         /* 
 283          * set sign bit of result and get magnitude of source 
 284          */
 285         if (srcp1 < 0) {
 286                 Dbl_setone_sign(resultp1);
 287                 Dint_negate(srcp1,srcp2);
 288         }
 289         else {
 290                 Dbl_setzero_sign(resultp1);
 291                 /* Check for zero */
 292                 if (srcp1 == 0 && srcp2 ==0) {
 293                         Dbl_setzero(resultp1,resultp2);
 294                         Dbl_copytoptr(resultp1,resultp2,dstptr);
 295                         return(NOEXCEPTION);
 296                 }
 297         }
 298         /*
 299          * Generate exponent and normalized mantissa
 300          */
 301         dst_exponent = 16;    /* initialize for normalization */
 302         if (srcp1 == 0) {
 303                 /*
 304                  * Check word for most significant bit set.  Returns
 305                  * a value in dst_exponent indicating the bit position,
 306                  * between -1 and 30.
 307                  */
 308                 Find_ms_one_bit(srcp2,dst_exponent);
 309                 /*  left justify source, with msb at bit position 1  */
 310                 if (dst_exponent >= 0) {
 311                         srcp1 = srcp2 << dst_exponent;    
 312                         srcp2 = 0;
 313                 }
 314                 else {
 315                         srcp1 = srcp2 >> 1;
 316                         srcp2 <<= 31;
 317                 }
 318                 /*
 319                  *  since msb set is in second word, need to 
 320                  *  adjust bit position count
 321                  */
 322                 dst_exponent += 32;
 323         }
 324         else {
 325                 /*
 326                  * Check word for most significant bit set.  Returns
 327                  * a value in dst_exponent indicating the bit position,
 328                  * between -1 and 30.
 329                  */
 330                 Find_ms_one_bit(srcp1,dst_exponent);
 331                 /*  left justify source, with msb at bit position 1  */
 332                 if (dst_exponent > 0) {
 333                         Variable_shift_double(srcp1,srcp2,(32-dst_exponent),
 334                          srcp1); 
 335                         srcp2 <<= dst_exponent;
 336                 }
 337                 /*
 338                  * If dst_exponent = 0, we don't need to shift anything.
 339                  * If dst_exponent = -1, src = - 2**63 so we won't need to 
 340                  * shift srcp2.
 341                  */
 342                 else srcp1 >>= -(dst_exponent);
 343         }
 344         Dbl_set_mantissap1(resultp1, srcp1 >> (DBL_EXP_LENGTH-1));
 345         Shiftdouble(srcp1,srcp2,DBL_EXP_LENGTH-1,resultp2);
 346         Dbl_set_exponent(resultp1, (62+DBL_BIAS) - dst_exponent);
 347 
 348         /* check for inexact */
 349         if (Dint_isinexact_to_dbl(srcp2)) {
 350                 switch (Rounding_mode()) {
 351                         case ROUNDPLUS: 
 352                                 if (Dbl_iszero_sign(resultp1)) {
 353                                         Dbl_increment(resultp1,resultp2);
 354                                 }
 355                                 break;
 356                         case ROUNDMINUS: 
 357                                 if (Dbl_isone_sign(resultp1)) {
 358                                         Dbl_increment(resultp1,resultp2);
 359                                 }
 360                                 break;
 361                         case ROUNDNEAREST:
 362                                 Dbl_roundnearest_from_dint(srcp2,resultp1,
 363                                 resultp2);
 364                 }
 365                 if (Is_inexacttrap_enabled()) {
 366                         Dbl_copytoptr(resultp1,resultp2,dstptr);
 367                         return(INEXACTEXCEPTION);
 368                 }
 369                 else Set_inexactflag();
 370         }
 371         Dbl_copytoptr(resultp1,resultp2,dstptr);
 372         return(NOEXCEPTION);
 373 }

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