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

fcnvxf.c (9169B)


      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/fcnvxf.c		$Revision: 1.1 $
     13 *
     14 *  Purpose:
     15 *	Single Fixed-point to Single Floating-point
     16 *	Single Fixed-point to Double Floating-point 
     17 *	Double Fixed-point to Single Floating-point 
     18 *	Double Fixed-point to Double Floating-point 
     19 *
     20 *  External Interfaces:
     21 *	dbl_to_dbl_fcnvxf(srcptr,nullptr,dstptr,status)
     22 *	dbl_to_sgl_fcnvxf(srcptr,nullptr,dstptr,status)
     23 *	sgl_to_dbl_fcnvxf(srcptr,nullptr,dstptr,status)
     24 *	sgl_to_sgl_fcnvxf(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 fixed-point to single floating-point format
     42 */
     43
     44int
     45sgl_to_sgl_fcnvxf(
     46		    int *srcptr,
     47		    unsigned int *nullptr,
     48		    sgl_floating_point *dstptr,
     49		    unsigned int *status)
     50{
     51	register int src, dst_exponent;
     52	register unsigned int result = 0;
     53
     54	src = *srcptr;
     55	/* 
     56	 * set sign bit of result and get magnitude of source 
     57	 */
     58	if (src < 0) {
     59		Sgl_setone_sign(result);  
     60		Int_negate(src);
     61	}
     62	else {
     63		Sgl_setzero_sign(result);
     64        	/* Check for zero */ 
     65        	if (src == 0) { 
     66                	Sgl_setzero(result); 
     67			*dstptr = result;
     68                	return(NOEXCEPTION); 
     69        	} 
     70	}
     71	/*
     72	 * Generate exponent and normalized mantissa
     73	 */
     74	dst_exponent = 16;    /* initialize for normalization */
     75	/*
     76	 * Check word for most significant bit set.  Returns
     77	 * a value in dst_exponent indicating the bit position,
     78	 * between -1 and 30.
     79	 */
     80	Find_ms_one_bit(src,dst_exponent);
     81	/*  left justify source, with msb at bit position 1  */
     82	if (dst_exponent >= 0) src <<= dst_exponent;
     83	else src = 1 << 30;
     84	Sgl_set_mantissa(result, src >> (SGL_EXP_LENGTH-1));
     85	Sgl_set_exponent(result, 30+SGL_BIAS - dst_exponent);
     86
     87	/* check for inexact */
     88	if (Int_isinexact_to_sgl(src)) {
     89		switch (Rounding_mode()) {
     90			case ROUNDPLUS: 
     91				if (Sgl_iszero_sign(result)) 
     92					Sgl_increment(result);
     93				break;
     94			case ROUNDMINUS: 
     95				if (Sgl_isone_sign(result)) 
     96					Sgl_increment(result);
     97				break;
     98			case ROUNDNEAREST:
     99				Sgl_roundnearest_from_int(src,result);
    100		}
    101		if (Is_inexacttrap_enabled()) {
    102			*dstptr = result;
    103			return(INEXACTEXCEPTION);
    104		}
    105		else Set_inexactflag();
    106	}
    107	*dstptr = result;
    108	return(NOEXCEPTION);
    109}
    110
    111/*
    112 *  Single Fixed-point to Double Floating-point 
    113 */
    114
    115int
    116sgl_to_dbl_fcnvxf(
    117		    int *srcptr,
    118		    unsigned int *nullptr,
    119		    dbl_floating_point *dstptr,
    120		    unsigned int *status)
    121{
    122	register int src, dst_exponent;
    123	register unsigned int resultp1 = 0, resultp2 = 0;
    124
    125	src = *srcptr;
    126	/* 
    127	 * set sign bit of result and get magnitude of source 
    128	 */
    129	if (src < 0) {
    130		Dbl_setone_sign(resultp1);  
    131		Int_negate(src);
    132	}
    133	else {
    134		Dbl_setzero_sign(resultp1);
    135        	/* Check for zero */
    136        	if (src == 0) {
    137                	Dbl_setzero(resultp1,resultp2);
    138                	Dbl_copytoptr(resultp1,resultp2,dstptr);
    139                	return(NOEXCEPTION);
    140        	}
    141	}
    142	/*
    143	 * Generate exponent and normalized mantissa
    144	 */
    145	dst_exponent = 16;    /* initialize for normalization */
    146	/*
    147	 * Check word for most significant bit set.  Returns
    148	 * a value in dst_exponent indicating the bit position,
    149	 * between -1 and 30.
    150	 */
    151	Find_ms_one_bit(src,dst_exponent);
    152	/*  left justify source, with msb at bit position 1  */
    153	if (dst_exponent >= 0) src <<= dst_exponent;
    154	else src = 1 << 30;
    155	Dbl_set_mantissap1(resultp1, src >> DBL_EXP_LENGTH - 1);
    156	Dbl_set_mantissap2(resultp2, src << (33-DBL_EXP_LENGTH));
    157	Dbl_set_exponent(resultp1, (30+DBL_BIAS) - dst_exponent);
    158	Dbl_copytoptr(resultp1,resultp2,dstptr);
    159	return(NOEXCEPTION);
    160}
    161
    162/*
    163 *  Double Fixed-point to Single Floating-point 
    164 */
    165
    166int
    167dbl_to_sgl_fcnvxf(
    168			dbl_integer *srcptr,
    169			unsigned int *nullptr,
    170			sgl_floating_point *dstptr,
    171			unsigned int *status)
    172{
    173	int dst_exponent, srcp1;
    174	unsigned int result = 0, srcp2;
    175
    176	Dint_copyfromptr(srcptr,srcp1,srcp2);
    177	/* 
    178	 * set sign bit of result and get magnitude of source 
    179	 */
    180	if (srcp1 < 0) {
    181		Sgl_setone_sign(result);  
    182		Dint_negate(srcp1,srcp2);
    183	}
    184	else {
    185		Sgl_setzero_sign(result);
    186        	/* Check for zero */
    187        	if (srcp1 == 0 && srcp2 == 0) {
    188                	Sgl_setzero(result);
    189                	*dstptr = result;
    190                	return(NOEXCEPTION);
    191		}
    192        }
    193	/*
    194	 * Generate exponent and normalized mantissa
    195	 */
    196	dst_exponent = 16;    /* initialize for normalization */
    197	if (srcp1 == 0) {
    198		/*
    199		 * Check word for most significant bit set.  Returns
    200		 * a value in dst_exponent indicating the bit position,
    201		 * between -1 and 30.
    202		 */
    203		Find_ms_one_bit(srcp2,dst_exponent);
    204		/*  left justify source, with msb at bit position 1  */
    205		if (dst_exponent >= 0) {
    206			srcp1 = srcp2 << dst_exponent;    
    207			srcp2 = 0;
    208		}
    209		else {
    210			srcp1 = srcp2 >> 1;
    211			srcp2 <<= 31; 
    212		}
    213		/*
    214		 *  since msb set is in second word, need to 
    215		 *  adjust bit position count
    216		 */
    217		dst_exponent += 32;
    218	}
    219	else {
    220		/*
    221		 * Check word for most significant bit set.  Returns
    222		 * a value in dst_exponent indicating the bit position,
    223		 * between -1 and 30.
    224		 *
    225		 */
    226		Find_ms_one_bit(srcp1,dst_exponent);
    227		/*  left justify source, with msb at bit position 1  */
    228		if (dst_exponent > 0) {
    229			Variable_shift_double(srcp1,srcp2,(32-dst_exponent),
    230			 srcp1); 
    231			srcp2 <<= dst_exponent;
    232		}
    233		/*
    234		 * If dst_exponent = 0, we don't need to shift anything.
    235		 * If dst_exponent = -1, src = - 2**63 so we won't need to 
    236		 * shift srcp2.
    237		 */
    238		else srcp1 >>= -(dst_exponent);
    239	}
    240	Sgl_set_mantissa(result, srcp1 >> SGL_EXP_LENGTH - 1);
    241	Sgl_set_exponent(result, (62+SGL_BIAS) - dst_exponent);
    242
    243	/* check for inexact */
    244	if (Dint_isinexact_to_sgl(srcp1,srcp2)) {
    245		switch (Rounding_mode()) {
    246			case ROUNDPLUS: 
    247				if (Sgl_iszero_sign(result)) 
    248					Sgl_increment(result);
    249				break;
    250			case ROUNDMINUS: 
    251				if (Sgl_isone_sign(result)) 
    252					Sgl_increment(result);
    253				break;
    254			case ROUNDNEAREST:
    255				Sgl_roundnearest_from_dint(srcp1,srcp2,result);
    256		}
    257		if (Is_inexacttrap_enabled()) {
    258			*dstptr = result;
    259			return(INEXACTEXCEPTION);
    260		}
    261		else Set_inexactflag();
    262	}
    263	*dstptr = result;
    264	return(NOEXCEPTION);
    265}
    266
    267/*
    268 *  Double Fixed-point to Double Floating-point 
    269 */
    270
    271int
    272dbl_to_dbl_fcnvxf(
    273		    dbl_integer *srcptr,
    274		    unsigned int *nullptr,
    275		    dbl_floating_point *dstptr,
    276		    unsigned int *status)
    277{
    278	register int srcp1, dst_exponent;
    279	register unsigned int srcp2, resultp1 = 0, resultp2 = 0;
    280
    281	Dint_copyfromptr(srcptr,srcp1,srcp2);
    282	/* 
    283	 * set sign bit of result and get magnitude of source 
    284	 */
    285	if (srcp1 < 0) {
    286		Dbl_setone_sign(resultp1);
    287		Dint_negate(srcp1,srcp2);
    288	}
    289	else {
    290		Dbl_setzero_sign(resultp1);
    291        	/* Check for zero */
    292        	if (srcp1 == 0 && srcp2 ==0) {
    293                	Dbl_setzero(resultp1,resultp2);
    294                	Dbl_copytoptr(resultp1,resultp2,dstptr);
    295                	return(NOEXCEPTION);
    296		}
    297        }
    298	/*
    299	 * Generate exponent and normalized mantissa
    300	 */
    301	dst_exponent = 16;    /* initialize for normalization */
    302	if (srcp1 == 0) {
    303		/*
    304		 * Check word for most significant bit set.  Returns
    305		 * a value in dst_exponent indicating the bit position,
    306		 * between -1 and 30.
    307		 */
    308		Find_ms_one_bit(srcp2,dst_exponent);
    309		/*  left justify source, with msb at bit position 1  */
    310		if (dst_exponent >= 0) {
    311			srcp1 = srcp2 << dst_exponent;    
    312			srcp2 = 0;
    313		}
    314		else {
    315			srcp1 = srcp2 >> 1;
    316			srcp2 <<= 31;
    317		}
    318		/*
    319		 *  since msb set is in second word, need to 
    320		 *  adjust bit position count
    321		 */
    322		dst_exponent += 32;
    323	}
    324	else {
    325		/*
    326		 * Check word for most significant bit set.  Returns
    327		 * a value in dst_exponent indicating the bit position,
    328		 * between -1 and 30.
    329		 */
    330		Find_ms_one_bit(srcp1,dst_exponent);
    331		/*  left justify source, with msb at bit position 1  */
    332		if (dst_exponent > 0) {
    333			Variable_shift_double(srcp1,srcp2,(32-dst_exponent),
    334			 srcp1); 
    335			srcp2 <<= dst_exponent;
    336		}
    337		/*
    338		 * If dst_exponent = 0, we don't need to shift anything.
    339		 * If dst_exponent = -1, src = - 2**63 so we won't need to 
    340		 * shift srcp2.
    341		 */
    342		else srcp1 >>= -(dst_exponent);
    343	}
    344	Dbl_set_mantissap1(resultp1, srcp1 >> (DBL_EXP_LENGTH-1));
    345	Shiftdouble(srcp1,srcp2,DBL_EXP_LENGTH-1,resultp2);
    346	Dbl_set_exponent(resultp1, (62+DBL_BIAS) - dst_exponent);
    347
    348	/* check for inexact */
    349	if (Dint_isinexact_to_dbl(srcp2)) {
    350		switch (Rounding_mode()) {
    351			case ROUNDPLUS: 
    352				if (Dbl_iszero_sign(resultp1)) {
    353					Dbl_increment(resultp1,resultp2);
    354				}
    355				break;
    356			case ROUNDMINUS: 
    357				if (Dbl_isone_sign(resultp1)) {
    358					Dbl_increment(resultp1,resultp2);
    359				}
    360				break;
    361			case ROUNDNEAREST:
    362				Dbl_roundnearest_from_dint(srcp2,resultp1,
    363				resultp2);
    364		}
    365		if (Is_inexacttrap_enabled()) {
    366			Dbl_copytoptr(resultp1,resultp2,dstptr);
    367			return(INEXACTEXCEPTION);
    368		}
    369		else Set_inexactflag();
    370	}
    371	Dbl_copytoptr(resultp1,resultp2,dstptr);
    372	return(NOEXCEPTION);
    373}