Home | History | Annotate | Line # | Download | only in spmath
fcnvxf.c revision 1.3.112.1
      1  1.3.112.1      yamt /*	$NetBSD: fcnvxf.c,v 1.3.112.1 2012/04/17 00:06:27 yamt Exp $	*/
      2        1.1  fredette 
      3        1.1  fredette /*	$OpenBSD: fcnvxf.c,v 1.5 2001/03/29 03:58:18 mickey Exp $	*/
      4        1.1  fredette 
      5        1.1  fredette /*
      6        1.1  fredette  * Copyright 1996 1995 by Open Software Foundation, Inc.
      7        1.1  fredette  *              All Rights Reserved
      8        1.1  fredette  *
      9        1.1  fredette  * Permission to use, copy, modify, and distribute this software and
     10        1.1  fredette  * its documentation for any purpose and without fee is hereby granted,
     11        1.1  fredette  * provided that the above copyright notice appears in all copies and
     12        1.1  fredette  * that both the copyright notice and this permission notice appear in
     13        1.1  fredette  * supporting documentation.
     14        1.1  fredette  *
     15        1.1  fredette  * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
     16        1.1  fredette  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     17        1.1  fredette  * FOR A PARTICULAR PURPOSE.
     18        1.1  fredette  *
     19        1.1  fredette  * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
     20        1.1  fredette  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
     21        1.1  fredette  * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
     22        1.1  fredette  * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
     23        1.1  fredette  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     24        1.1  fredette  *
     25        1.1  fredette  */
     26        1.1  fredette /*
     27        1.1  fredette  * pmk1.1
     28        1.1  fredette  */
     29        1.1  fredette /*
     30        1.1  fredette  * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
     31        1.1  fredette  *
     32        1.1  fredette  * To anyone who acknowledges that this file is provided "AS IS"
     33        1.1  fredette  * without any express or implied warranty:
     34        1.1  fredette  *     permission to use, copy, modify, and distribute this file
     35        1.1  fredette  * for any purpose is hereby granted without fee, provided that
     36        1.1  fredette  * the above copyright notice and this notice appears in all
     37        1.1  fredette  * copies, and that the name of Hewlett-Packard Company not be
     38        1.1  fredette  * used in advertising or publicity pertaining to distribution
     39        1.1  fredette  * of the software without specific, written prior permission.
     40        1.1  fredette  * Hewlett-Packard Company makes no representations about the
     41        1.1  fredette  * suitability of this software for any purpose.
     42        1.1  fredette  */
     43        1.2     lukem 
     44        1.2     lukem #include <sys/cdefs.h>
     45  1.3.112.1      yamt __KERNEL_RCSID(0, "$NetBSD: fcnvxf.c,v 1.3.112.1 2012/04/17 00:06:27 yamt Exp $");
     46        1.1  fredette 
     47        1.1  fredette #include "../spmath/float.h"
     48        1.1  fredette #include "../spmath/sgl_float.h"
     49        1.1  fredette #include "../spmath/dbl_float.h"
     50        1.1  fredette #include "../spmath/cnv_float.h"
     51        1.1  fredette 
     52        1.1  fredette /*
     53        1.1  fredette  *  Convert single fixed-point to single floating-point format
     54        1.1  fredette  */
     55        1.1  fredette int
     56  1.3.112.1      yamt sgl_to_sgl_fcnvxf(int *srcptr, sgl_floating_point *dstptr,
     57  1.3.112.1      yamt     unsigned int *status)
     58        1.1  fredette {
     59        1.1  fredette 	register int src, dst_exponent;
     60        1.1  fredette 	register unsigned int result = 0;
     61        1.1  fredette 
     62        1.1  fredette 	src = *srcptr;
     63        1.1  fredette 	/*
     64        1.1  fredette 	 * set sign bit of result and get magnitude of source
     65        1.1  fredette 	 */
     66        1.1  fredette 	if (src < 0) {
     67        1.1  fredette 		Sgl_setone_sign(result);
     68        1.1  fredette 		Int_negate(src);
     69        1.1  fredette 	}
     70        1.1  fredette 	else {
     71        1.1  fredette 		Sgl_setzero_sign(result);
     72        1.1  fredette 		/* Check for zero */
     73        1.1  fredette 		if (src == 0) {
     74        1.1  fredette 			Sgl_setzero(result);
     75        1.1  fredette 			*dstptr = result;
     76        1.1  fredette 			return(NOEXCEPTION);
     77        1.1  fredette 		}
     78        1.1  fredette 	}
     79        1.1  fredette 	/*
     80        1.1  fredette 	 * Generate exponent and normalized mantissa
     81        1.1  fredette 	 */
     82        1.1  fredette 	dst_exponent = 16;    /* initialize for normalization */
     83        1.1  fredette 	/*
     84        1.1  fredette 	 * Check word for most significant bit set.  Returns
     85        1.1  fredette 	 * a value in dst_exponent indicating the bit position,
     86        1.1  fredette 	 * between -1 and 30.
     87        1.1  fredette 	 */
     88        1.1  fredette 	Find_ms_one_bit(src,dst_exponent);
     89        1.1  fredette 	/*  left justify source, with msb at bit position 1  */
     90        1.1  fredette 	if (dst_exponent >= 0) src <<= dst_exponent;
     91        1.1  fredette 	else src = 1 << 30;
     92        1.1  fredette 	Sgl_set_mantissa(result, src >> (SGL_EXP_LENGTH-1));
     93        1.1  fredette 	Sgl_set_exponent(result, 30+SGL_BIAS - dst_exponent);
     94        1.1  fredette 
     95        1.1  fredette 	/* check for inexact */
     96        1.1  fredette 	if (Int_isinexact_to_sgl(src)) {
     97        1.1  fredette 		switch (Rounding_mode()) {
     98        1.1  fredette 			case ROUNDPLUS:
     99        1.1  fredette 				if (Sgl_iszero_sign(result))
    100        1.1  fredette 					Sgl_increment(result);
    101        1.1  fredette 				break;
    102        1.1  fredette 			case ROUNDMINUS:
    103        1.1  fredette 				if (Sgl_isone_sign(result))
    104        1.1  fredette 					Sgl_increment(result);
    105        1.1  fredette 				break;
    106        1.1  fredette 			case ROUNDNEAREST:
    107        1.1  fredette 				Sgl_roundnearest_from_int(src,result);
    108        1.1  fredette 		}
    109        1.1  fredette 		if (Is_inexacttrap_enabled()) {
    110        1.1  fredette 			*dstptr = result;
    111        1.1  fredette 			return(INEXACTEXCEPTION);
    112        1.1  fredette 		}
    113        1.1  fredette 		else Set_inexactflag();
    114        1.1  fredette 	}
    115        1.1  fredette 	*dstptr = result;
    116        1.1  fredette 	return(NOEXCEPTION);
    117        1.1  fredette }
    118        1.1  fredette 
    119        1.1  fredette /*
    120        1.1  fredette  *  Single Fixed-point to Double Floating-point
    121        1.1  fredette  */
    122        1.1  fredette int
    123  1.3.112.1      yamt sgl_to_dbl_fcnvxf(int *srcptr, dbl_floating_point *dstptr,
    124  1.3.112.1      yamt     unsigned int *status)
    125        1.1  fredette {
    126        1.1  fredette 	register int src, dst_exponent;
    127        1.1  fredette 	register unsigned int resultp1 = 0, resultp2 = 0;
    128        1.1  fredette 
    129        1.1  fredette 	src = *srcptr;
    130        1.1  fredette 	/*
    131        1.1  fredette 	 * set sign bit of result and get magnitude of source
    132        1.1  fredette 	 */
    133        1.1  fredette 	if (src < 0) {
    134        1.1  fredette 		Dbl_setone_sign(resultp1);
    135        1.1  fredette 		Int_negate(src);
    136        1.1  fredette 	}
    137        1.1  fredette 	else {
    138        1.1  fredette 		Dbl_setzero_sign(resultp1);
    139        1.1  fredette 		/* Check for zero */
    140        1.1  fredette 		if (src == 0) {
    141        1.1  fredette 			Dbl_setzero(resultp1,resultp2);
    142        1.1  fredette 			Dbl_copytoptr(resultp1,resultp2,dstptr);
    143        1.1  fredette 			return(NOEXCEPTION);
    144        1.1  fredette 		}
    145        1.1  fredette 	}
    146        1.1  fredette 	/*
    147        1.1  fredette 	 * Generate exponent and normalized mantissa
    148        1.1  fredette 	 */
    149        1.1  fredette 	dst_exponent = 16;    /* initialize for normalization */
    150        1.1  fredette 	/*
    151        1.1  fredette 	 * Check word for most significant bit set.  Returns
    152        1.1  fredette 	 * a value in dst_exponent indicating the bit position,
    153        1.1  fredette 	 * between -1 and 30.
    154        1.1  fredette 	 */
    155        1.1  fredette 	Find_ms_one_bit(src,dst_exponent);
    156        1.1  fredette 	/*  left justify source, with msb at bit position 1  */
    157        1.1  fredette 	if (dst_exponent >= 0) src <<= dst_exponent;
    158        1.1  fredette 	else src = 1 << 30;
    159        1.1  fredette 	Dbl_set_mantissap1(resultp1, (src >> (DBL_EXP_LENGTH - 1)));
    160        1.1  fredette 	Dbl_set_mantissap2(resultp2, (src << (33-DBL_EXP_LENGTH)));
    161        1.1  fredette 	Dbl_set_exponent(resultp1, (30+DBL_BIAS) - dst_exponent);
    162        1.1  fredette 	Dbl_copytoptr(resultp1,resultp2,dstptr);
    163        1.1  fredette 	return(NOEXCEPTION);
    164        1.1  fredette }
    165        1.1  fredette 
    166        1.1  fredette /*
    167        1.1  fredette  *  Double Fixed-point to Single Floating-point
    168        1.1  fredette  */
    169        1.1  fredette int
    170  1.3.112.1      yamt dbl_to_sgl_fcnvxf(dbl_integer *srcptr, sgl_floating_point *dstptr,
    171  1.3.112.1      yamt     unsigned int *status)
    172        1.1  fredette {
    173        1.1  fredette 	int dst_exponent, srcp1;
    174        1.1  fredette 	unsigned int result = 0, srcp2;
    175        1.1  fredette 
    176        1.1  fredette 	Dint_copyfromptr(srcptr,srcp1,srcp2);
    177        1.1  fredette 	/*
    178        1.1  fredette 	 * set sign bit of result and get magnitude of source
    179        1.1  fredette 	 */
    180        1.1  fredette 	if (srcp1 < 0) {
    181        1.1  fredette 		Sgl_setone_sign(result);
    182        1.1  fredette 		Dint_negate(srcp1,srcp2);
    183        1.1  fredette 	}
    184        1.1  fredette 	else {
    185        1.1  fredette 		Sgl_setzero_sign(result);
    186        1.1  fredette 		/* Check for zero */
    187        1.1  fredette 		if (srcp1 == 0 && srcp2 == 0) {
    188        1.1  fredette 			Sgl_setzero(result);
    189        1.1  fredette 			*dstptr = result;
    190        1.1  fredette 			return(NOEXCEPTION);
    191        1.1  fredette 		}
    192        1.1  fredette 	}
    193        1.1  fredette 	/*
    194        1.1  fredette 	 * Generate exponent and normalized mantissa
    195        1.1  fredette 	 */
    196        1.1  fredette 	dst_exponent = 16;    /* initialize for normalization */
    197        1.1  fredette 	if (srcp1 == 0) {
    198        1.1  fredette 		/*
    199        1.1  fredette 		 * Check word for most significant bit set.  Returns
    200        1.1  fredette 		 * a value in dst_exponent indicating the bit position,
    201        1.1  fredette 		 * between -1 and 30.
    202        1.1  fredette 		 */
    203        1.1  fredette 		Find_ms_one_bit(srcp2,dst_exponent);
    204        1.1  fredette 		/*  left justify source, with msb at bit position 1  */
    205        1.1  fredette 		if (dst_exponent >= 0) {
    206        1.1  fredette 			srcp1 = srcp2 << dst_exponent;
    207        1.1  fredette 			srcp2 = 0;
    208        1.1  fredette 		}
    209        1.1  fredette 		else {
    210        1.1  fredette 			srcp1 = srcp2 >> 1;
    211        1.1  fredette 			srcp2 <<= 31;
    212        1.1  fredette 		}
    213        1.1  fredette 		/*
    214        1.1  fredette 		 *  since msb set is in second word, need to
    215        1.1  fredette 		 *  adjust bit position count
    216        1.1  fredette 		 */
    217        1.1  fredette 		dst_exponent += 32;
    218        1.1  fredette 	}
    219        1.1  fredette 	else {
    220        1.1  fredette 		/*
    221        1.1  fredette 		 * Check word for most significant bit set.  Returns
    222        1.1  fredette 		 * a value in dst_exponent indicating the bit position,
    223        1.1  fredette 		 * between -1 and 30.
    224        1.1  fredette 		 *
    225        1.1  fredette 		 */
    226        1.1  fredette 		Find_ms_one_bit(srcp1,dst_exponent);
    227        1.1  fredette 		/*  left justify source, with msb at bit position 1  */
    228        1.1  fredette 		if (dst_exponent > 0) {
    229        1.1  fredette 			Variable_shift_double(srcp1,srcp2,(32-dst_exponent),
    230        1.1  fredette 			 srcp1);
    231        1.1  fredette 			srcp2 <<= dst_exponent;
    232        1.1  fredette 		}
    233        1.1  fredette 		/*
    234        1.1  fredette 		 * If dst_exponent = 0, we don't need to shift anything.
    235        1.1  fredette 		 * If dst_exponent = -1, src = - 2**63 so we won't need to
    236        1.1  fredette 		 * shift srcp2.
    237        1.1  fredette 		 */
    238        1.1  fredette 		else srcp1 >>= -(dst_exponent);
    239        1.1  fredette 	}
    240        1.1  fredette 	Sgl_set_mantissa(result, (srcp1 >> (SGL_EXP_LENGTH - 1)));
    241        1.1  fredette 	Sgl_set_exponent(result, (62+SGL_BIAS) - dst_exponent);
    242        1.1  fredette 
    243        1.1  fredette 	/* check for inexact */
    244        1.1  fredette 	if (Dint_isinexact_to_sgl(srcp1,srcp2)) {
    245        1.1  fredette 		switch (Rounding_mode()) {
    246        1.1  fredette 			case ROUNDPLUS:
    247        1.1  fredette 				if (Sgl_iszero_sign(result))
    248        1.1  fredette 					Sgl_increment(result);
    249        1.1  fredette 				break;
    250        1.1  fredette 			case ROUNDMINUS:
    251        1.1  fredette 				if (Sgl_isone_sign(result))
    252        1.1  fredette 					Sgl_increment(result);
    253        1.1  fredette 				break;
    254        1.1  fredette 			case ROUNDNEAREST:
    255        1.1  fredette 				Sgl_roundnearest_from_dint(srcp1,srcp2,result);
    256        1.1  fredette 		}
    257        1.1  fredette 		if (Is_inexacttrap_enabled()) {
    258        1.1  fredette 			*dstptr = result;
    259        1.1  fredette 			return(INEXACTEXCEPTION);
    260        1.1  fredette 		}
    261        1.1  fredette 		else Set_inexactflag();
    262        1.1  fredette 	}
    263        1.1  fredette 	*dstptr = result;
    264        1.1  fredette 	return(NOEXCEPTION);
    265        1.1  fredette }
    266        1.1  fredette 
    267        1.1  fredette /*
    268        1.1  fredette  *  Double Fixed-point to Double Floating-point
    269        1.1  fredette  */
    270        1.1  fredette int
    271  1.3.112.1      yamt dbl_to_dbl_fcnvxf(dbl_integer *srcptr, dbl_floating_point *dstptr,
    272  1.3.112.1      yamt     unsigned int *status)
    273        1.1  fredette {
    274        1.1  fredette 	register int srcp1, dst_exponent;
    275        1.1  fredette 	register unsigned int srcp2, resultp1 = 0, resultp2 = 0;
    276        1.1  fredette 
    277        1.1  fredette 	Dint_copyfromptr(srcptr,srcp1,srcp2);
    278        1.1  fredette 	/*
    279        1.1  fredette 	 * set sign bit of result and get magnitude of source
    280        1.1  fredette 	 */
    281        1.1  fredette 	if (srcp1 < 0) {
    282        1.1  fredette 		Dbl_setone_sign(resultp1);
    283        1.1  fredette 		Dint_negate(srcp1,srcp2);
    284        1.1  fredette 	}
    285        1.1  fredette 	else {
    286        1.1  fredette 		Dbl_setzero_sign(resultp1);
    287        1.1  fredette 		/* Check for zero */
    288        1.1  fredette 		if (srcp1 == 0 && srcp2 ==0) {
    289        1.1  fredette 			Dbl_setzero(resultp1,resultp2);
    290        1.1  fredette 			Dbl_copytoptr(resultp1,resultp2,dstptr);
    291        1.1  fredette 			return(NOEXCEPTION);
    292        1.1  fredette 		}
    293        1.1  fredette 	}
    294        1.1  fredette 	/*
    295        1.1  fredette 	 * Generate exponent and normalized mantissa
    296        1.1  fredette 	 */
    297        1.1  fredette 	dst_exponent = 16;    /* initialize for normalization */
    298        1.1  fredette 	if (srcp1 == 0) {
    299        1.1  fredette 		/*
    300        1.1  fredette 		 * Check word for most significant bit set.  Returns
    301        1.1  fredette 		 * a value in dst_exponent indicating the bit position,
    302        1.1  fredette 		 * between -1 and 30.
    303        1.1  fredette 		 */
    304        1.1  fredette 		Find_ms_one_bit(srcp2,dst_exponent);
    305        1.1  fredette 		/*  left justify source, with msb at bit position 1  */
    306        1.1  fredette 		if (dst_exponent >= 0) {
    307        1.1  fredette 			srcp1 = srcp2 << dst_exponent;
    308        1.1  fredette 			srcp2 = 0;
    309        1.1  fredette 		}
    310        1.1  fredette 		else {
    311        1.1  fredette 			srcp1 = srcp2 >> 1;
    312        1.1  fredette 			srcp2 <<= 31;
    313        1.1  fredette 		}
    314        1.1  fredette 		/*
    315        1.1  fredette 		 *  since msb set is in second word, need to
    316        1.1  fredette 		 *  adjust bit position count
    317        1.1  fredette 		 */
    318        1.1  fredette 		dst_exponent += 32;
    319        1.1  fredette 	}
    320        1.1  fredette 	else {
    321        1.1  fredette 		/*
    322        1.1  fredette 		 * Check word for most significant bit set.  Returns
    323        1.1  fredette 		 * a value in dst_exponent indicating the bit position,
    324        1.1  fredette 		 * between -1 and 30.
    325        1.1  fredette 		 */
    326        1.1  fredette 		Find_ms_one_bit(srcp1,dst_exponent);
    327        1.1  fredette 		/*  left justify source, with msb at bit position 1  */
    328        1.1  fredette 		if (dst_exponent > 0) {
    329        1.1  fredette 			Variable_shift_double(srcp1,srcp2,(32-dst_exponent),
    330        1.1  fredette 			 srcp1);
    331        1.1  fredette 			srcp2 <<= dst_exponent;
    332        1.1  fredette 		}
    333        1.1  fredette 		/*
    334        1.1  fredette 		 * If dst_exponent = 0, we don't need to shift anything.
    335        1.1  fredette 		 * If dst_exponent = -1, src = - 2**63 so we won't need to
    336        1.1  fredette 		 * shift srcp2.
    337        1.1  fredette 		 */
    338        1.1  fredette 		else srcp1 >>= -(dst_exponent);
    339        1.1  fredette 	}
    340        1.1  fredette 	Dbl_set_mantissap1(resultp1, srcp1 >> (DBL_EXP_LENGTH-1));
    341        1.1  fredette 	Shiftdouble(srcp1,srcp2,DBL_EXP_LENGTH-1,resultp2);
    342        1.1  fredette 	Dbl_set_exponent(resultp1, (62+DBL_BIAS) - dst_exponent);
    343        1.1  fredette 
    344        1.1  fredette 	/* check for inexact */
    345        1.1  fredette 	if (Dint_isinexact_to_dbl(srcp2)) {
    346        1.1  fredette 		switch (Rounding_mode()) {
    347        1.1  fredette 			case ROUNDPLUS:
    348        1.1  fredette 				if (Dbl_iszero_sign(resultp1)) {
    349        1.1  fredette 					Dbl_increment(resultp1,resultp2);
    350        1.1  fredette 				}
    351        1.1  fredette 				break;
    352        1.1  fredette 			case ROUNDMINUS:
    353        1.1  fredette 				if (Dbl_isone_sign(resultp1)) {
    354        1.1  fredette 					Dbl_increment(resultp1,resultp2);
    355        1.1  fredette 				}
    356        1.1  fredette 				break;
    357        1.1  fredette 			case ROUNDNEAREST:
    358        1.1  fredette 				Dbl_roundnearest_from_dint(srcp2,resultp1,
    359        1.1  fredette 				resultp2);
    360        1.1  fredette 		}
    361        1.1  fredette 		if (Is_inexacttrap_enabled()) {
    362        1.1  fredette 			Dbl_copytoptr(resultp1,resultp2,dstptr);
    363        1.1  fredette 			return(INEXACTEXCEPTION);
    364        1.1  fredette 		}
    365        1.1  fredette 		else Set_inexactflag();
    366        1.1  fredette 	}
    367        1.1  fredette 	Dbl_copytoptr(resultp1,resultp2,dstptr);
    368        1.1  fredette 	return(NOEXCEPTION);
    369        1.1  fredette }
    370