linux/arch/parisc/math-emu/fcnvfxt.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/fcnvfxt.c             $Revision: 1.1 $
  26 *
  27 *  Purpose:
  28 *      Single Floating-point to Single Fixed-point /w truncated result
  29 *      Single Floating-point to Double Fixed-point /w truncated result
  30 *      Double Floating-point to Single Fixed-point /w truncated result
  31 *      Double Floating-point to Double Fixed-point /w truncated result
  32 *
  33 *  External Interfaces:
  34 *      dbl_to_dbl_fcnvfxt(srcptr,nullptr,dstptr,status)
  35 *      dbl_to_sgl_fcnvfxt(srcptr,nullptr,dstptr,status)
  36 *      sgl_to_dbl_fcnvfxt(srcptr,nullptr,dstptr,status)
  37 *      sgl_to_sgl_fcnvfxt(srcptr,nullptr,dstptr,status)
  38 *
  39 *  Internal Interfaces:
  40 *
  41 *  Theory:
  42 *      <<please update with a overview of the operation of this file>>
  43 *
  44 * END_DESC
  45*/
  46
  47
  48#include "float.h"
  49#include "sgl_float.h"
  50#include "dbl_float.h"
  51#include "cnv_float.h"
  52
  53/*
  54 *  Convert single floating-point to single fixed-point format
  55 *  with truncated result
  56 */
  57/*ARGSUSED*/
  58int
  59sgl_to_sgl_fcnvfxt(
  60                    sgl_floating_point *srcptr,
  61                    unsigned int *nullptr,
  62                    int *dstptr,
  63                    unsigned int *status)
  64{
  65        register unsigned int src, temp;
  66        register int src_exponent, result;
  67
  68        src = *srcptr;
  69        src_exponent = Sgl_exponent(src) - SGL_BIAS;
  70
  71        /* 
  72         * Test for overflow
  73         */
  74        if (src_exponent > SGL_FX_MAX_EXP) {
  75                /* check for MININT */
  76                if ((src_exponent > SGL_FX_MAX_EXP + 1) || 
  77                Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) {
  78                        if (Sgl_iszero_sign(src)) result = 0x7fffffff;
  79                        else result = 0x80000000; 
  80
  81                        if (Is_invalidtrap_enabled()) {
  82                            return(INVALIDEXCEPTION);
  83                        }
  84                        Set_invalidflag();
  85                        *dstptr = result;
  86                        return(NOEXCEPTION);
  87                }
  88        }
  89        /*
  90         * Generate result
  91         */
  92        if (src_exponent >= 0) {
  93                temp = src;
  94                Sgl_clear_signexponent_set_hidden(temp);
  95                Int_from_sgl_mantissa(temp,src_exponent);
  96                if (Sgl_isone_sign(src))  result = -Sgl_all(temp);
  97                else result = Sgl_all(temp);
  98                *dstptr = result;
  99
 100                /* check for inexact */
 101                if (Sgl_isinexact_to_fix(src,src_exponent)) {
 102                        if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
 103                        else Set_inexactflag();
 104                }
 105        }
 106        else {
 107                *dstptr = 0;
 108
 109                /* check for inexact */
 110                if (Sgl_isnotzero_exponentmantissa(src)) {
 111                        if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
 112                        else Set_inexactflag();
 113                }
 114        }
 115        return(NOEXCEPTION);
 116}
 117
 118/*
 119 *  Single Floating-point to Double Fixed-point 
 120 */
 121/*ARGSUSED*/
 122int
 123sgl_to_dbl_fcnvfxt(
 124                    sgl_floating_point *srcptr,
 125                    unsigned int *nullptr,
 126                    dbl_integer *dstptr,
 127                    unsigned int *status)
 128{
 129        register int src_exponent, resultp1;
 130        register unsigned int src, temp, resultp2;
 131
 132        src = *srcptr;
 133        src_exponent = Sgl_exponent(src) - SGL_BIAS;
 134
 135        /* 
 136         * Test for overflow
 137         */
 138        if (src_exponent > DBL_FX_MAX_EXP) {
 139                /* check for MININT */
 140                if ((src_exponent > DBL_FX_MAX_EXP + 1) || 
 141                Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) {
 142                        if (Sgl_iszero_sign(src)) {
 143                              resultp1 = 0x7fffffff;
 144                              resultp2 = 0xffffffff;
 145                        }
 146                        else {
 147                            resultp1 = 0x80000000; 
 148                            resultp2 = 0;
 149                        }
 150                        if (Is_invalidtrap_enabled()) {
 151                            return(INVALIDEXCEPTION);
 152                        }
 153                        Set_invalidflag();
 154                        Dint_copytoptr(resultp1,resultp2,dstptr);
 155                        return(NOEXCEPTION);
 156                }
 157                Dint_set_minint(resultp1,resultp2);
 158                Dint_copytoptr(resultp1,resultp2,dstptr);
 159                return(NOEXCEPTION);
 160        }
 161        /*
 162         * Generate result
 163         */
 164        if (src_exponent >= 0) {
 165                temp = src;
 166                Sgl_clear_signexponent_set_hidden(temp);
 167                Dint_from_sgl_mantissa(temp,src_exponent,resultp1,resultp2);
 168                if (Sgl_isone_sign(src)) {
 169                        Dint_setone_sign(resultp1,resultp2);
 170                }
 171                Dint_copytoptr(resultp1,resultp2,dstptr);
 172
 173                /* check for inexact */
 174                if (Sgl_isinexact_to_fix(src,src_exponent)) {
 175                        if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
 176                        else Set_inexactflag();
 177                }
 178        }
 179        else {
 180                Dint_setzero(resultp1,resultp2);
 181                Dint_copytoptr(resultp1,resultp2,dstptr);
 182
 183                /* check for inexact */
 184                if (Sgl_isnotzero_exponentmantissa(src)) {
 185                        if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
 186                        else Set_inexactflag();
 187                }
 188        }
 189        return(NOEXCEPTION);
 190}
 191
 192/*
 193 *  Double Floating-point to Single Fixed-point 
 194 */
 195/*ARGSUSED*/
 196int
 197dbl_to_sgl_fcnvfxt(
 198                        dbl_floating_point *srcptr,
 199                        unsigned int *nullptr,
 200                        int *dstptr,
 201                        unsigned int *status)
 202{
 203        register unsigned int srcp1, srcp2, tempp1, tempp2;
 204        register int src_exponent, result;
 205
 206        Dbl_copyfromptr(srcptr,srcp1,srcp2);
 207        src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
 208
 209        /* 
 210         * Test for overflow
 211         */
 212        if (src_exponent > SGL_FX_MAX_EXP) {
 213                /* check for MININT */
 214                if (Dbl_isoverflow_to_int(src_exponent,srcp1,srcp2)) {
 215                        if (Dbl_iszero_sign(srcp1)) result = 0x7fffffff;
 216                        else result = 0x80000000; 
 217
 218                        if (Is_invalidtrap_enabled()) {
 219                            return(INVALIDEXCEPTION);
 220                        }
 221                        Set_invalidflag();
 222                        *dstptr = result;
 223                        return(NOEXCEPTION);
 224                }
 225        }
 226        /*
 227         * Generate result
 228         */
 229        if (src_exponent >= 0) {
 230                tempp1 = srcp1;
 231                tempp2 = srcp2;
 232                Dbl_clear_signexponent_set_hidden(tempp1);
 233                Int_from_dbl_mantissa(tempp1,tempp2,src_exponent);
 234                if (Dbl_isone_sign(srcp1) && (src_exponent <= SGL_FX_MAX_EXP))
 235                        result = -Dbl_allp1(tempp1);
 236                else result = Dbl_allp1(tempp1);
 237                *dstptr = result;
 238
 239                /* check for inexact */
 240                if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
 241                        if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
 242                        else Set_inexactflag();
 243                }
 244        }
 245        else {
 246                *dstptr = 0;
 247
 248                /* check for inexact */
 249                if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
 250                        if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
 251                        else Set_inexactflag();
 252                }
 253        }
 254        return(NOEXCEPTION);
 255}
 256
 257/*
 258 *  Double Floating-point to Double Fixed-point 
 259 */
 260/*ARGSUSED*/
 261int
 262dbl_to_dbl_fcnvfxt(
 263                        dbl_floating_point *srcptr,
 264                        unsigned int *nullptr,
 265                        dbl_integer *dstptr,
 266                        unsigned int *status)
 267{
 268        register int src_exponent, resultp1;
 269        register unsigned int srcp1, srcp2, tempp1, tempp2, resultp2;
 270
 271        Dbl_copyfromptr(srcptr,srcp1,srcp2);
 272        src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
 273
 274        /* 
 275         * Test for overflow
 276         */
 277        if (src_exponent > DBL_FX_MAX_EXP) {
 278                /* check for MININT */
 279                if ((src_exponent > DBL_FX_MAX_EXP + 1) || 
 280                Dbl_isnotzero_mantissa(srcp1,srcp2) || Dbl_iszero_sign(srcp1)) {
 281                        if (Dbl_iszero_sign(srcp1)) {
 282                              resultp1 = 0x7fffffff;
 283                              resultp2 = 0xffffffff;
 284                        }
 285                        else {
 286                            resultp1 = 0x80000000; 
 287                            resultp2 = 0;
 288                        }
 289                        if (Is_invalidtrap_enabled()) {
 290                            return(INVALIDEXCEPTION);
 291                        }
 292                        Set_invalidflag();
 293                        Dint_copytoptr(resultp1,resultp2,dstptr);
 294                        return(NOEXCEPTION);
 295                }
 296        }
 297        /*
 298         * Generate result
 299         */
 300        if (src_exponent >= 0) {
 301                tempp1 = srcp1;
 302                tempp2 = srcp2;
 303                Dbl_clear_signexponent_set_hidden(tempp1);
 304                Dint_from_dbl_mantissa(tempp1,tempp2,src_exponent,
 305                resultp1,resultp2);
 306                if (Dbl_isone_sign(srcp1)) {
 307                        Dint_setone_sign(resultp1,resultp2);
 308                }
 309                Dint_copytoptr(resultp1,resultp2,dstptr);
 310
 311                /* check for inexact */
 312                if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
 313                        if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
 314                        else Set_inexactflag();
 315                }
 316        }
 317        else {
 318                Dint_setzero(resultp1,resultp2);
 319                Dint_copytoptr(resultp1,resultp2,dstptr);
 320
 321                /* check for inexact */
 322                if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
 323                        if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
 324                        else Set_inexactflag();
 325                }
 326        }
 327        return(NOEXCEPTION);
 328}
 329