linux/arch/parisc/math-emu/fcnvfut.c
<<
>>
Prefs
   1/*
   2 * Linux/PA-RISC Project (http://www.parisc-linux.org/)
   3 *
   4 * Floating-point emulation code
   5 *  Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
   6 *
   7 *    This program is free software; you can redistribute it and/or modify
   8 *    it under the terms of the GNU General Public License as published by
   9 *    the Free Software Foundation; either version 2, or (at your option)
  10 *    any later version.
  11 *
  12 *    This program is distributed in the hope that it will be useful,
  13 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 *    GNU General Public License for more details.
  16 *
  17 *    You should have received a copy of the GNU General Public License
  18 *    along with this program; if not, write to the Free Software
  19 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  20 */
  21/*
  22 * BEGIN_DESC
  23 *
  24 *  File:
  25 *      @(#)    pa/spmath/fcnvfut.c             $Revision: 1.1 $
  26 *
  27 *  Purpose:
  28 *      Floating-point to Unsigned Fixed-point Converts with Truncation
  29 *
  30 *  External Interfaces:
  31 *      dbl_to_dbl_fcnvfut(srcptr,nullptr,dstptr,status)
  32 *      dbl_to_sgl_fcnvfut(srcptr,nullptr,dstptr,status)
  33 *      sgl_to_dbl_fcnvfut(srcptr,nullptr,dstptr,status)
  34 *      sgl_to_sgl_fcnvfut(srcptr,nullptr,dstptr,status)
  35 *
  36 *  Internal Interfaces:
  37 *
  38 *  Theory:
  39 *      <<please update with a overview of the operation of this file>>
  40 *
  41 * END_DESC
  42*/
  43
  44
  45#include "float.h"
  46#include "sgl_float.h"
  47#include "dbl_float.h"
  48#include "cnv_float.h"
  49
  50/************************************************************************
  51 *  Floating-point to Unsigned Fixed-point Converts with Truncation     *
  52 ************************************************************************/
  53
  54/*
  55 *  Convert single floating-point to single fixed-point format
  56 *  with truncated result
  57 */
  58/*ARGSUSED*/
  59int
  60sgl_to_sgl_fcnvfut (sgl_floating_point * srcptr, unsigned int *nullptr,
  61                    unsigned int *dstptr, unsigned int *status)
  62{
  63        register unsigned int src, result;
  64        register int src_exponent;
  65
  66        src = *srcptr;
  67        src_exponent = Sgl_exponent(src) - SGL_BIAS;
  68
  69        /* 
  70         * Test for overflow
  71         */
  72        if (src_exponent > SGL_FX_MAX_EXP + 1) {
  73                if (Sgl_isone_sign(src)) {
  74                        result = 0;
  75                } else {
  76                        result = 0xffffffff;
  77                }
  78                if (Is_invalidtrap_enabled()) {
  79                        return(INVALIDEXCEPTION);
  80                }
  81                Set_invalidflag();
  82                *dstptr = result;
  83                return(NOEXCEPTION);
  84        }
  85        /*
  86         * Generate result
  87         */
  88        if (src_exponent >= 0) {
  89                /* 
  90                 * Check sign.
  91                 * If negative, trap unimplemented.
  92                 */
  93                if (Sgl_isone_sign(src)) {
  94                        result = 0;
  95                        if (Is_invalidtrap_enabled()) {
  96                                return(INVALIDEXCEPTION);
  97                        }
  98                        Set_invalidflag();
  99                        *dstptr = result;
 100                        return(NOEXCEPTION);
 101                }
 102                Sgl_clear_signexponent_set_hidden(src);
 103                Suint_from_sgl_mantissa(src,src_exponent,result);
 104                *dstptr = result;
 105
 106                /* check for inexact */
 107                if (Sgl_isinexact_to_unsigned(src,src_exponent)) {
 108                        if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
 109                        else Set_inexactflag();
 110                }
 111        }
 112        else {
 113                *dstptr = 0;
 114
 115                /* check for inexact */
 116                if (Sgl_isnotzero_exponentmantissa(src)) {
 117                        if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
 118                        else Set_inexactflag();
 119                }
 120        }
 121        return(NOEXCEPTION);
 122}
 123
 124/*
 125 *  Single Floating-point to Double Unsigned Fixed 
 126 */
 127/*ARGSUSED*/
 128int
 129sgl_to_dbl_fcnvfut (sgl_floating_point * srcptr, unsigned int *nullptr,
 130                    dbl_unsigned * dstptr, unsigned int *status)
 131{
 132        register int src_exponent;
 133        register unsigned int src, resultp1, resultp2;
 134
 135        src = *srcptr;
 136        src_exponent = Sgl_exponent(src) - SGL_BIAS;
 137
 138        /* 
 139         * Test for overflow
 140         */
 141        if (src_exponent > DBL_FX_MAX_EXP + 1) {
 142                if (Sgl_isone_sign(src)) {
 143                        resultp1 = resultp2 = 0;
 144                } else {
 145                        resultp1 = resultp2 = 0xffffffff;
 146                }
 147                if (Is_invalidtrap_enabled()) {
 148                        return(INVALIDEXCEPTION);
 149                }
 150                Set_invalidflag();
 151                Duint_copytoptr(resultp1,resultp2,dstptr);
 152                return(NOEXCEPTION);
 153        }
 154        /*
 155         * Generate result
 156         */
 157        if (src_exponent >= 0) {
 158                /* 
 159                 * Check sign.
 160                 * If negative, trap unimplemented.
 161                 */
 162                if (Sgl_isone_sign(src)) {
 163                        resultp1 = resultp2 = 0;
 164                        if (Is_invalidtrap_enabled()) {
 165                                return(INVALIDEXCEPTION);
 166                        }
 167                        Set_invalidflag();
 168                        Duint_copytoptr(resultp1,resultp2,dstptr);
 169                        return(NOEXCEPTION);
 170                }
 171                Sgl_clear_signexponent_set_hidden(src);
 172                Duint_from_sgl_mantissa(src,src_exponent,resultp1,resultp2);
 173                Duint_copytoptr(resultp1,resultp2,dstptr);
 174
 175                /* check for inexact */
 176                if (Sgl_isinexact_to_unsigned(src,src_exponent)) {
 177                        if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
 178                        else Set_inexactflag();
 179                }
 180        }
 181        else {
 182                Duint_setzero(resultp1,resultp2);
 183                Duint_copytoptr(resultp1,resultp2,dstptr);
 184
 185                /* check for inexact */
 186                if (Sgl_isnotzero_exponentmantissa(src)) {
 187                        if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
 188                        else Set_inexactflag();
 189                }
 190        }
 191        return(NOEXCEPTION);
 192}
 193
 194/*
 195 *  Double Floating-point to Single Unsigned Fixed 
 196 */
 197/*ARGSUSED*/
 198int
 199dbl_to_sgl_fcnvfut (dbl_floating_point * srcptr, unsigned int *nullptr,
 200                    unsigned int *dstptr, unsigned int *status)
 201{
 202        register unsigned int srcp1, srcp2, result;
 203        register int src_exponent;
 204
 205        Dbl_copyfromptr(srcptr,srcp1,srcp2);
 206        src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
 207
 208        /* 
 209         * Test for overflow
 210         */
 211        if (src_exponent > SGL_FX_MAX_EXP + 1) {
 212                if (Dbl_isone_sign(srcp1)) {
 213                        result = 0;
 214                } else {
 215                        result = 0xffffffff;
 216                }
 217                if (Is_invalidtrap_enabled()) {
 218                        return(INVALIDEXCEPTION);
 219                }
 220                Set_invalidflag();
 221                *dstptr = result;
 222                return(NOEXCEPTION);
 223        }
 224        /*
 225         * Generate result
 226         */
 227        if (src_exponent >= 0) {
 228                /* 
 229                 * Check sign.
 230                 * If negative, trap unimplemented.
 231                 */
 232                if (Dbl_isone_sign(srcp1)) {
 233                        result = 0;
 234                        if (Is_invalidtrap_enabled()) {
 235                                return(INVALIDEXCEPTION);
 236                        }
 237                        Set_invalidflag();
 238                        *dstptr = result;
 239                        return(NOEXCEPTION);
 240                }
 241                Dbl_clear_signexponent_set_hidden(srcp1);
 242                Suint_from_dbl_mantissa(srcp1,srcp2,src_exponent,result);
 243                *dstptr = result;
 244
 245                /* check for inexact */
 246                if (Dbl_isinexact_to_unsigned(srcp1,srcp2,src_exponent)) {
 247                        if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
 248                        else Set_inexactflag();
 249                }
 250        }
 251        else {
 252                *dstptr = 0;
 253
 254                /* check for inexact */
 255                if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
 256                        if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
 257                        else Set_inexactflag();
 258                }
 259        }
 260        return(NOEXCEPTION);
 261}
 262
 263/*
 264 *  Double Floating-point to Double Unsigned Fixed 
 265 */
 266/*ARGSUSED*/
 267int
 268dbl_to_dbl_fcnvfut (dbl_floating_point * srcptr, unsigned int *nullptr,
 269                    dbl_unsigned * dstptr, unsigned int *status)
 270{
 271        register int src_exponent;
 272        register unsigned int srcp1, srcp2, resultp1, resultp2;
 273
 274        Dbl_copyfromptr(srcptr,srcp1,srcp2);
 275        src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
 276
 277        /* 
 278         * Test for overflow
 279         */
 280        if (src_exponent > DBL_FX_MAX_EXP + 1) {
 281                if (Dbl_isone_sign(srcp1)) {
 282                        resultp1 = resultp2 = 0;
 283                } else {
 284                        resultp1 = resultp2 = 0xffffffff;
 285                }
 286                if (Is_invalidtrap_enabled()) {
 287                        return(INVALIDEXCEPTION);
 288                }
 289                Set_invalidflag();
 290                Duint_copytoptr(resultp1,resultp2,dstptr);
 291                return(NOEXCEPTION);
 292        }
 293        /*
 294         * Generate result
 295         */
 296        if (src_exponent >= 0) {
 297                /* 
 298                 * Check sign.
 299                 * If negative, trap unimplemented.
 300                 */
 301                if (Dbl_isone_sign(srcp1)) {
 302                        resultp1 = resultp2 = 0;
 303                        if (Is_invalidtrap_enabled()) {
 304                                return(INVALIDEXCEPTION);
 305                        }
 306                        Set_invalidflag();
 307                        Duint_copytoptr(resultp1,resultp2,dstptr);
 308                        return(NOEXCEPTION);
 309                }
 310                Dbl_clear_signexponent_set_hidden(srcp1);
 311                Duint_from_dbl_mantissa(srcp1,srcp2,src_exponent,
 312                  resultp1,resultp2);
 313                Duint_copytoptr(resultp1,resultp2,dstptr);
 314
 315                /* check for inexact */
 316                if (Dbl_isinexact_to_unsigned(srcp1,srcp2,src_exponent)) {
 317                        if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
 318                        else Set_inexactflag();
 319                }
 320        }
 321        else {
 322                Duint_setzero(resultp1,resultp2);
 323                Duint_copytoptr(resultp1,resultp2,dstptr);
 324
 325                /* check for inexact */
 326                if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
 327                        if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
 328                        else Set_inexactflag();
 329                }
 330        }
 331        return(NOEXCEPTION);
 332}
 333