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

fcnvuf.c (7479B)


      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/fcnvuf.c		$Revision: 1.1 $
     13 *
     14 *  Purpose:
     15 *	Fixed point to Floating-point Converts
     16 *
     17 *  External Interfaces:
     18 *	dbl_to_dbl_fcnvuf(srcptr,nullptr,dstptr,status)
     19 *	dbl_to_sgl_fcnvuf(srcptr,nullptr,dstptr,status)
     20 *	sgl_to_dbl_fcnvuf(srcptr,nullptr,dstptr,status)
     21 *	sgl_to_sgl_fcnvuf(srcptr,nullptr,dstptr,status)
     22 *
     23 *  Internal Interfaces:
     24 *
     25 *  Theory:
     26 *	<<please update with a overview of the operation of this file>>
     27 *
     28 * END_DESC
     29*/
     30
     31
     32#include "float.h"
     33#include "sgl_float.h"
     34#include "dbl_float.h"
     35#include "cnv_float.h"
     36
     37/************************************************************************
     38 *  Fixed point to Floating-point Converts				*
     39 ************************************************************************/
     40
     41/*
     42 *  Convert Single Unsigned Fixed to Single Floating-point format
     43 */
     44
     45int
     46sgl_to_sgl_fcnvuf(
     47			unsigned int *srcptr,
     48			unsigned int *nullptr,
     49			sgl_floating_point *dstptr,
     50			unsigned int *status)
     51{
     52	register unsigned int src, result = 0;
     53	register int dst_exponent;
     54
     55	src = *srcptr;
     56
     57	/* Check for zero */ 
     58	if (src == 0) { 
     59	       	Sgl_setzero(result); 
     60		*dstptr = result;
     61	       	return(NOEXCEPTION); 
     62	} 
     63	/*
     64	 * Generate exponent and normalized mantissa
     65	 */
     66	dst_exponent = 16;    /* initialize for normalization */
     67	/*
     68	 * Check word for most significant bit set.  Returns
     69	 * a value in dst_exponent indicating the bit position,
     70	 * between -1 and 30.
     71	 */
     72	Find_ms_one_bit(src,dst_exponent);
     73	/*  left justify source, with msb at bit position 0  */
     74	src <<= dst_exponent+1;
     75	Sgl_set_mantissa(result, src >> SGL_EXP_LENGTH);
     76	Sgl_set_exponent(result, 30+SGL_BIAS - dst_exponent);
     77
     78	/* check for inexact */
     79	if (Suint_isinexact_to_sgl(src)) {
     80		switch (Rounding_mode()) {
     81			case ROUNDPLUS: 
     82				Sgl_increment(result);
     83				break;
     84			case ROUNDMINUS: /* never negative */
     85				break;
     86			case ROUNDNEAREST:
     87				Sgl_roundnearest_from_suint(src,result);
     88				break;
     89		}
     90		if (Is_inexacttrap_enabled()) {
     91			*dstptr = result;
     92			return(INEXACTEXCEPTION);
     93		}
     94		else Set_inexactflag();
     95	}
     96	*dstptr = result;
     97	return(NOEXCEPTION);
     98}
     99
    100/*
    101 *  Single Unsigned Fixed to Double Floating-point 
    102 */
    103
    104int
    105sgl_to_dbl_fcnvuf(
    106			unsigned int *srcptr,
    107			unsigned int *nullptr,
    108			dbl_floating_point *dstptr,
    109			unsigned int *status)
    110{
    111	register int dst_exponent;
    112	register unsigned int src, resultp1 = 0, resultp2 = 0;
    113
    114	src = *srcptr;
    115
    116	/* Check for zero */
    117	if (src == 0) {
    118	       	Dbl_setzero(resultp1,resultp2);
    119	       	Dbl_copytoptr(resultp1,resultp2,dstptr);
    120	       	return(NOEXCEPTION);
    121	}
    122	/*
    123	 * Generate exponent and normalized mantissa
    124	 */
    125	dst_exponent = 16;    /* initialize for normalization */
    126	/*
    127	 * Check word for most significant bit set.  Returns
    128	 * a value in dst_exponent indicating the bit position,
    129	 * between -1 and 30.
    130	 */
    131	Find_ms_one_bit(src,dst_exponent);
    132	/*  left justify source, with msb at bit position 0  */
    133	src <<= dst_exponent+1;
    134	Dbl_set_mantissap1(resultp1, src >> DBL_EXP_LENGTH);
    135	Dbl_set_mantissap2(resultp2, src << (32-DBL_EXP_LENGTH));
    136	Dbl_set_exponent(resultp1, (30+DBL_BIAS) - dst_exponent);
    137	Dbl_copytoptr(resultp1,resultp2,dstptr);
    138	return(NOEXCEPTION);
    139}
    140
    141/*
    142 *  Double Unsigned Fixed to Single Floating-point 
    143 */
    144
    145int
    146dbl_to_sgl_fcnvuf(
    147			dbl_unsigned *srcptr,
    148			unsigned int *nullptr,
    149			sgl_floating_point *dstptr,
    150			unsigned int *status)
    151{
    152	int dst_exponent;
    153	unsigned int srcp1, srcp2, result = 0;
    154
    155	Duint_copyfromptr(srcptr,srcp1,srcp2);
    156
    157	/* Check for zero */
    158	if (srcp1 == 0 && srcp2 == 0) {
    159	       	Sgl_setzero(result);
    160	       	*dstptr = result;
    161	       	return(NOEXCEPTION);
    162	}
    163	/*
    164	 * Generate exponent and normalized mantissa
    165	 */
    166	dst_exponent = 16;    /* initialize for normalization */
    167	if (srcp1 == 0) {
    168		/*
    169		 * Check word for most significant bit set.  Returns
    170		 * a value in dst_exponent indicating the bit position,
    171		 * between -1 and 30.
    172		 */
    173		Find_ms_one_bit(srcp2,dst_exponent);
    174		/*  left justify source, with msb at bit position 0  */
    175		srcp1 = srcp2 << dst_exponent+1;    
    176		srcp2 = 0;
    177		/*
    178		 *  since msb set is in second word, need to 
    179		 *  adjust bit position count
    180		 */
    181		dst_exponent += 32;
    182	}
    183	else {
    184		/*
    185		 * Check word for most significant bit set.  Returns
    186		 * a value in dst_exponent indicating the bit position,
    187		 * between -1 and 30.
    188		 *
    189		 */
    190		Find_ms_one_bit(srcp1,dst_exponent);
    191		/*  left justify source, with msb at bit position 0  */
    192		if (dst_exponent >= 0) {
    193			Variable_shift_double(srcp1,srcp2,(31-dst_exponent),
    194			 srcp1); 
    195			srcp2 <<= dst_exponent+1;
    196		}
    197	}
    198	Sgl_set_mantissa(result, srcp1 >> SGL_EXP_LENGTH);
    199	Sgl_set_exponent(result, (62+SGL_BIAS) - dst_exponent);
    200
    201	/* check for inexact */
    202	if (Duint_isinexact_to_sgl(srcp1,srcp2)) {
    203		switch (Rounding_mode()) {
    204			case ROUNDPLUS: 
    205				Sgl_increment(result);
    206				break;
    207			case ROUNDMINUS: /* never negative */
    208				break;
    209			case ROUNDNEAREST:
    210				Sgl_roundnearest_from_duint(srcp1,srcp2,result);
    211				break;
    212		}
    213		if (Is_inexacttrap_enabled()) {
    214			*dstptr = result;
    215			return(INEXACTEXCEPTION);
    216		}
    217		else Set_inexactflag();
    218	}
    219	*dstptr = result;
    220	return(NOEXCEPTION);
    221}
    222
    223/*
    224 *  Double Unsigned Fixed to Double Floating-point 
    225 */
    226
    227int
    228dbl_to_dbl_fcnvuf(
    229		    dbl_unsigned *srcptr,
    230		    unsigned int *nullptr,
    231		    dbl_floating_point *dstptr,
    232		    unsigned int *status)
    233{
    234	register int dst_exponent;
    235	register unsigned int srcp1, srcp2, resultp1 = 0, resultp2 = 0;
    236
    237	Duint_copyfromptr(srcptr,srcp1,srcp2);
    238
    239	/* Check for zero */
    240	if (srcp1 == 0 && srcp2 ==0) {
    241	       	Dbl_setzero(resultp1,resultp2);
    242	       	Dbl_copytoptr(resultp1,resultp2,dstptr);
    243	       	return(NOEXCEPTION);
    244	}
    245	/*
    246	 * Generate exponent and normalized mantissa
    247	 */
    248	dst_exponent = 16;    /* initialize for normalization */
    249	if (srcp1 == 0) {
    250		/*
    251		 * Check word for most significant bit set.  Returns
    252		 * a value in dst_exponent indicating the bit position,
    253		 * between -1 and 30.
    254		 */
    255		Find_ms_one_bit(srcp2,dst_exponent);
    256		/*  left justify source, with msb at bit position 0  */
    257		srcp1 = srcp2 << dst_exponent+1;
    258		srcp2 = 0;
    259		/*
    260		 *  since msb set is in second word, need to 
    261		 *  adjust bit position count
    262		 */
    263		dst_exponent += 32;
    264	}
    265	else {
    266		/*
    267		 * Check word for most significant bit set.  Returns
    268		 * a value in dst_exponent indicating the bit position,
    269		 * between -1 and 30.
    270		 */
    271		Find_ms_one_bit(srcp1,dst_exponent);
    272		/*  left justify source, with msb at bit position 0  */
    273		if (dst_exponent >= 0) {
    274			Variable_shift_double(srcp1,srcp2,(31-dst_exponent),
    275			 srcp1); 
    276			srcp2 <<= dst_exponent+1;
    277		}
    278	}
    279	Dbl_set_mantissap1(resultp1, srcp1 >> DBL_EXP_LENGTH);
    280	Shiftdouble(srcp1,srcp2,DBL_EXP_LENGTH,resultp2);
    281	Dbl_set_exponent(resultp1, (62+DBL_BIAS) - dst_exponent);
    282
    283	/* check for inexact */
    284	if (Duint_isinexact_to_dbl(srcp2)) {
    285		switch (Rounding_mode()) {
    286			case ROUNDPLUS: 
    287				Dbl_increment(resultp1,resultp2);
    288				break;
    289			case ROUNDMINUS: /* never negative */
    290				break;
    291			case ROUNDNEAREST:
    292				Dbl_roundnearest_from_duint(srcp2,resultp1,
    293				resultp2);
    294				break;
    295		}
    296		if (Is_inexacttrap_enabled()) {
    297			Dbl_copytoptr(resultp1,resultp2,dstptr);
    298			return(INEXACTEXCEPTION);
    299		}
    300		else Set_inexactflag();
    301	}
    302	Dbl_copytoptr(resultp1,resultp2,dstptr);
    303	return(NOEXCEPTION);
    304}
    305