cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

fcnvff.c (8721B)


      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*/
     40int
     41sgl_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*/
    127int
    128dbl_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}