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

fcnvfxt.c (7969B)


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