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

frnd.c (6484B)


      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 *  Purpose:
     12 *	Single Floating-point Round to Integer
     13 *	Double Floating-point Round to Integer
     14 *	Quad Floating-point Round to Integer (returns unimplemented)
     15 *
     16 *  External Interfaces:
     17 *	dbl_frnd(srcptr,nullptr,dstptr,status)
     18 *	sgl_frnd(srcptr,nullptr,dstptr,status)
     19 *
     20 * END_DESC
     21*/
     22
     23
     24#include "float.h"
     25#include "sgl_float.h"
     26#include "dbl_float.h"
     27#include "cnv_float.h"
     28
     29/*
     30 *  Single Floating-point Round to Integer
     31 */
     32
     33/*ARGSUSED*/
     34int
     35sgl_frnd(sgl_floating_point *srcptr,
     36	unsigned int *nullptr,
     37	sgl_floating_point *dstptr,
     38	unsigned int *status)
     39{
     40	register unsigned int src, result;
     41	register int src_exponent;
     42	register boolean inexact = FALSE;
     43
     44	src = *srcptr;
     45        /*
     46         * check source operand for NaN or infinity
     47         */
     48        if ((src_exponent = Sgl_exponent(src)) == SGL_INFINITY_EXPONENT) {
     49                /*
     50                 * is signaling NaN?
     51                 */
     52                if (Sgl_isone_signaling(src)) {
     53                        /* trap if INVALIDTRAP enabled */
     54                        if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
     55                        /* make NaN quiet */
     56                        Set_invalidflag();
     57                        Sgl_set_quiet(src);
     58                }
     59                /*
     60                 * return quiet NaN or infinity
     61                 */
     62                *dstptr = src;
     63                return(NOEXCEPTION);
     64        }
     65	/* 
     66	 * Need to round?
     67	 */
     68	if ((src_exponent -= SGL_BIAS) >= SGL_P - 1) {
     69		*dstptr = src;
     70		return(NOEXCEPTION);
     71	}
     72	/*
     73	 * Generate result
     74	 */
     75	if (src_exponent >= 0) {
     76		Sgl_clear_exponent_set_hidden(src);
     77		result = src;
     78		Sgl_rightshift(result,(SGL_P-1) - (src_exponent));
     79		/* check for inexact */
     80		if (Sgl_isinexact_to_fix(src,src_exponent)) {
     81			inexact = TRUE;
     82			/*  round result  */
     83			switch (Rounding_mode()) {
     84			case ROUNDPLUS:
     85			     if (Sgl_iszero_sign(src)) Sgl_increment(result);
     86			     break;
     87			case ROUNDMINUS:
     88			     if (Sgl_isone_sign(src)) Sgl_increment(result);
     89			     break;
     90			case ROUNDNEAREST:
     91			     if (Sgl_isone_roundbit(src,src_exponent))
     92			        if (Sgl_isone_stickybit(src,src_exponent) 
     93				|| (Sgl_isone_lowmantissa(result))) 
     94					Sgl_increment(result);
     95			} 
     96		}
     97		Sgl_leftshift(result,(SGL_P-1) - (src_exponent));
     98		if (Sgl_isone_hiddenoverflow(result)) 
     99			Sgl_set_exponent(result,src_exponent + (SGL_BIAS+1));
    100		else Sgl_set_exponent(result,src_exponent + SGL_BIAS);
    101	}
    102	else {
    103		result = src;  		/* set sign */
    104		Sgl_setzero_exponentmantissa(result);
    105		/* check for inexact */
    106		if (Sgl_isnotzero_exponentmantissa(src)) {
    107			inexact = TRUE;
    108			/*  round result  */
    109			switch (Rounding_mode()) {
    110			case ROUNDPLUS:
    111			     if (Sgl_iszero_sign(src)) 
    112				Sgl_set_exponent(result,SGL_BIAS);
    113			     break;
    114			case ROUNDMINUS:
    115			     if (Sgl_isone_sign(src)) 
    116				Sgl_set_exponent(result,SGL_BIAS);
    117			     break;
    118			case ROUNDNEAREST:
    119			     if (src_exponent == -1)
    120			        if (Sgl_isnotzero_mantissa(src))
    121				   Sgl_set_exponent(result,SGL_BIAS);
    122			} 
    123		}
    124	}
    125	*dstptr = result;
    126	if (inexact) {
    127		if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
    128		else Set_inexactflag();
    129	}
    130	return(NOEXCEPTION);
    131} 
    132
    133/*
    134 *  Double Floating-point Round to Integer
    135 */
    136
    137/*ARGSUSED*/
    138int
    139dbl_frnd(
    140	dbl_floating_point *srcptr,
    141	unsigned int *nullptr,
    142	dbl_floating_point *dstptr,
    143	unsigned int *status)
    144{
    145	register unsigned int srcp1, srcp2, resultp1, resultp2;
    146	register int src_exponent;
    147	register boolean inexact = FALSE;
    148
    149	Dbl_copyfromptr(srcptr,srcp1,srcp2);
    150        /*
    151         * check source operand for NaN or infinity
    152         */
    153        if ((src_exponent = Dbl_exponent(srcp1)) == DBL_INFINITY_EXPONENT) {
    154                /*
    155                 * is signaling NaN?
    156                 */
    157                if (Dbl_isone_signaling(srcp1)) {
    158                        /* trap if INVALIDTRAP enabled */
    159                        if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
    160                        /* make NaN quiet */
    161                        Set_invalidflag();
    162                        Dbl_set_quiet(srcp1);
    163                }
    164                /*
    165                 * return quiet NaN or infinity
    166                 */
    167                Dbl_copytoptr(srcp1,srcp2,dstptr);
    168                return(NOEXCEPTION);
    169        }
    170	/* 
    171	 * Need to round?
    172	 */
    173	if ((src_exponent -= DBL_BIAS) >= DBL_P - 1) {
    174		Dbl_copytoptr(srcp1,srcp2,dstptr);
    175		return(NOEXCEPTION);
    176	}
    177	/*
    178	 * Generate result
    179	 */
    180	if (src_exponent >= 0) {
    181		Dbl_clear_exponent_set_hidden(srcp1);
    182		resultp1 = srcp1;
    183		resultp2 = srcp2;
    184		Dbl_rightshift(resultp1,resultp2,(DBL_P-1) - (src_exponent));
    185		/* check for inexact */
    186		if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
    187			inexact = TRUE;
    188			/*  round result  */
    189			switch (Rounding_mode()) {
    190			case ROUNDPLUS:
    191			     if (Dbl_iszero_sign(srcp1)) 
    192				Dbl_increment(resultp1,resultp2);
    193			     break;
    194			case ROUNDMINUS:
    195			     if (Dbl_isone_sign(srcp1)) 
    196				Dbl_increment(resultp1,resultp2);
    197			     break;
    198			case ROUNDNEAREST:
    199			     if (Dbl_isone_roundbit(srcp1,srcp2,src_exponent))
    200			      if (Dbl_isone_stickybit(srcp1,srcp2,src_exponent) 
    201				  || (Dbl_isone_lowmantissap2(resultp2))) 
    202					Dbl_increment(resultp1,resultp2);
    203			} 
    204		}
    205		Dbl_leftshift(resultp1,resultp2,(DBL_P-1) - (src_exponent));
    206		if (Dbl_isone_hiddenoverflow(resultp1))
    207			Dbl_set_exponent(resultp1,src_exponent + (DBL_BIAS+1));
    208		else Dbl_set_exponent(resultp1,src_exponent + DBL_BIAS);
    209	}
    210	else {
    211		resultp1 = srcp1;  /* set sign */
    212		Dbl_setzero_exponentmantissa(resultp1,resultp2);
    213		/* check for inexact */
    214		if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
    215			inexact = TRUE;
    216			/*  round result  */
    217			switch (Rounding_mode()) {
    218			case ROUNDPLUS:
    219			     if (Dbl_iszero_sign(srcp1)) 
    220				Dbl_set_exponent(resultp1,DBL_BIAS);
    221			     break;
    222			case ROUNDMINUS:
    223			     if (Dbl_isone_sign(srcp1)) 
    224				Dbl_set_exponent(resultp1,DBL_BIAS);
    225			     break;
    226			case ROUNDNEAREST:
    227			     if (src_exponent == -1)
    228			        if (Dbl_isnotzero_mantissa(srcp1,srcp2))
    229				   Dbl_set_exponent(resultp1,DBL_BIAS);
    230			} 
    231		}
    232	}
    233	Dbl_copytoptr(resultp1,resultp2,dstptr);
    234	if (inexact) {
    235		if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
    236		else Set_inexactflag();
    237	}
    238	return(NOEXCEPTION);
    239}