1*7eec34daSmickey /* $OpenBSD: fcnvxf.c,v 1.7 2003/04/10 17:27:58 mickey Exp $ */
2c2feb252Smickey /*
3c2feb252Smickey (c) Copyright 1986 HEWLETT-PACKARD COMPANY
4c2feb252Smickey To anyone who acknowledges that this file is provided "AS IS"
5c2feb252Smickey without any express or implied warranty:
6c2feb252Smickey permission to use, copy, modify, and distribute this file
7c2feb252Smickey for any purpose is hereby granted without fee, provided that
8c2feb252Smickey the above copyright notice and this notice appears in all
9c2feb252Smickey copies, and that the name of Hewlett-Packard Company not be
10c2feb252Smickey used in advertising or publicity pertaining to distribution
11c2feb252Smickey of the software without specific, written prior permission.
12c2feb252Smickey Hewlett-Packard Company makes no representations about the
13c2feb252Smickey suitability of this software for any purpose.
14c2feb252Smickey */
15c2feb252Smickey /* @(#)fcnvxf.c: Revision: 2.7.88.1 Date: 93/12/07 15:06:16 */
16b94afd46Smickey
17c2feb252Smickey #include "float.h"
18c2feb252Smickey #include "sgl_float.h"
19c2feb252Smickey #include "dbl_float.h"
20c2feb252Smickey #include "cnv_float.h"
218a472b3eSmickey
228a472b3eSmickey /*
238a472b3eSmickey * Convert single fixed-point to single floating-point format
248a472b3eSmickey */
25b94afd46Smickey int
sgl_to_sgl_fcnvxf(srcptr,null,dstptr,status)26*7eec34daSmickey sgl_to_sgl_fcnvxf(srcptr, null, dstptr, status)
27*7eec34daSmickey int *srcptr, *null;
288a472b3eSmickey sgl_floating_point *dstptr;
29b94afd46Smickey unsigned int *status;
308a472b3eSmickey {
318a472b3eSmickey register int src, dst_exponent;
328a472b3eSmickey register unsigned int result = 0;
338a472b3eSmickey
348a472b3eSmickey src = *srcptr;
358a472b3eSmickey /*
368a472b3eSmickey * set sign bit of result and get magnitude of source
378a472b3eSmickey */
388a472b3eSmickey if (src < 0) {
398a472b3eSmickey Sgl_setone_sign(result);
408a472b3eSmickey Int_negate(src);
418a472b3eSmickey }
428a472b3eSmickey else {
438a472b3eSmickey Sgl_setzero_sign(result);
448a472b3eSmickey /* Check for zero */
458a472b3eSmickey if (src == 0) {
468a472b3eSmickey Sgl_setzero(result);
478a472b3eSmickey *dstptr = result;
488a472b3eSmickey return(NOEXCEPTION);
498a472b3eSmickey }
508a472b3eSmickey }
518a472b3eSmickey /*
528a472b3eSmickey * Generate exponent and normalized mantissa
538a472b3eSmickey */
548a472b3eSmickey dst_exponent = 16; /* initialize for normalization */
558a472b3eSmickey /*
568a472b3eSmickey * Check word for most significant bit set. Returns
578a472b3eSmickey * a value in dst_exponent indicating the bit position,
588a472b3eSmickey * between -1 and 30.
598a472b3eSmickey */
608a472b3eSmickey Find_ms_one_bit(src,dst_exponent);
618a472b3eSmickey /* left justify source, with msb at bit position 1 */
628a472b3eSmickey if (dst_exponent >= 0) src <<= dst_exponent;
638a472b3eSmickey else src = 1 << 30;
648a472b3eSmickey Sgl_set_mantissa(result, src >> (SGL_EXP_LENGTH-1));
658a472b3eSmickey Sgl_set_exponent(result, 30+SGL_BIAS - dst_exponent);
668a472b3eSmickey
678a472b3eSmickey /* check for inexact */
688a472b3eSmickey if (Int_isinexact_to_sgl(src)) {
698a472b3eSmickey switch (Rounding_mode()) {
708a472b3eSmickey case ROUNDPLUS:
718a472b3eSmickey if (Sgl_iszero_sign(result))
728a472b3eSmickey Sgl_increment(result);
738a472b3eSmickey break;
748a472b3eSmickey case ROUNDMINUS:
758a472b3eSmickey if (Sgl_isone_sign(result))
768a472b3eSmickey Sgl_increment(result);
778a472b3eSmickey break;
788a472b3eSmickey case ROUNDNEAREST:
798a472b3eSmickey Sgl_roundnearest_from_int(src,result);
808a472b3eSmickey }
818a472b3eSmickey if (Is_inexacttrap_enabled()) {
828a472b3eSmickey *dstptr = result;
838a472b3eSmickey return(INEXACTEXCEPTION);
848a472b3eSmickey }
858a472b3eSmickey else Set_inexactflag();
868a472b3eSmickey }
878a472b3eSmickey *dstptr = result;
888a472b3eSmickey return(NOEXCEPTION);
898a472b3eSmickey }
908a472b3eSmickey
918a472b3eSmickey /*
928a472b3eSmickey * Single Fixed-point to Double Floating-point
938a472b3eSmickey */
94b94afd46Smickey int
sgl_to_dbl_fcnvxf(srcptr,null,dstptr,status)95*7eec34daSmickey sgl_to_dbl_fcnvxf(srcptr, null, dstptr, status)
96*7eec34daSmickey int *srcptr, *null;
978a472b3eSmickey dbl_floating_point *dstptr;
98b94afd46Smickey unsigned int *status;
998a472b3eSmickey {
1008a472b3eSmickey register int src, dst_exponent;
1018a472b3eSmickey register unsigned int resultp1 = 0, resultp2 = 0;
1028a472b3eSmickey
1038a472b3eSmickey src = *srcptr;
1048a472b3eSmickey /*
1058a472b3eSmickey * set sign bit of result and get magnitude of source
1068a472b3eSmickey */
1078a472b3eSmickey if (src < 0) {
1088a472b3eSmickey Dbl_setone_sign(resultp1);
1098a472b3eSmickey Int_negate(src);
1108a472b3eSmickey }
1118a472b3eSmickey else {
1128a472b3eSmickey Dbl_setzero_sign(resultp1);
1138a472b3eSmickey /* Check for zero */
1148a472b3eSmickey if (src == 0) {
1158a472b3eSmickey Dbl_setzero(resultp1,resultp2);
1168a472b3eSmickey Dbl_copytoptr(resultp1,resultp2,dstptr);
1178a472b3eSmickey return(NOEXCEPTION);
1188a472b3eSmickey }
1198a472b3eSmickey }
1208a472b3eSmickey /*
1218a472b3eSmickey * Generate exponent and normalized mantissa
1228a472b3eSmickey */
1238a472b3eSmickey dst_exponent = 16; /* initialize for normalization */
1248a472b3eSmickey /*
1258a472b3eSmickey * Check word for most significant bit set. Returns
1268a472b3eSmickey * a value in dst_exponent indicating the bit position,
1278a472b3eSmickey * between -1 and 30.
1288a472b3eSmickey */
1298a472b3eSmickey Find_ms_one_bit(src,dst_exponent);
1308a472b3eSmickey /* left justify source, with msb at bit position 1 */
1318a472b3eSmickey if (dst_exponent >= 0) src <<= dst_exponent;
1328a472b3eSmickey else src = 1 << 30;
133b94afd46Smickey Dbl_set_mantissap1(resultp1, (src >> (DBL_EXP_LENGTH - 1)));
134b94afd46Smickey Dbl_set_mantissap2(resultp2, (src << (33-DBL_EXP_LENGTH)));
1358a472b3eSmickey Dbl_set_exponent(resultp1, (30+DBL_BIAS) - dst_exponent);
1368a472b3eSmickey Dbl_copytoptr(resultp1,resultp2,dstptr);
1378a472b3eSmickey return(NOEXCEPTION);
1388a472b3eSmickey }
1398a472b3eSmickey
1408a472b3eSmickey /*
1418a472b3eSmickey * Double Fixed-point to Single Floating-point
1428a472b3eSmickey */
143b94afd46Smickey int
dbl_to_sgl_fcnvxf(srcptr,null,dstptr,status)144*7eec34daSmickey dbl_to_sgl_fcnvxf(srcptr, null, dstptr, status)
145*7eec34daSmickey dbl_integer *srcptr, *null;
1468a472b3eSmickey sgl_floating_point *dstptr;
147b94afd46Smickey unsigned int *status;
1488a472b3eSmickey {
1498a472b3eSmickey int dst_exponent, srcp1;
1508a472b3eSmickey unsigned int result = 0, srcp2;
1518a472b3eSmickey
1528a472b3eSmickey Dint_copyfromptr(srcptr,srcp1,srcp2);
1538a472b3eSmickey /*
1548a472b3eSmickey * set sign bit of result and get magnitude of source
1558a472b3eSmickey */
1568a472b3eSmickey if (srcp1 < 0) {
1578a472b3eSmickey Sgl_setone_sign(result);
1588a472b3eSmickey Dint_negate(srcp1,srcp2);
1598a472b3eSmickey }
1608a472b3eSmickey else {
1618a472b3eSmickey Sgl_setzero_sign(result);
1628a472b3eSmickey /* Check for zero */
1638a472b3eSmickey if (srcp1 == 0 && srcp2 == 0) {
1648a472b3eSmickey Sgl_setzero(result);
1658a472b3eSmickey *dstptr = result;
1668a472b3eSmickey return(NOEXCEPTION);
1678a472b3eSmickey }
1688a472b3eSmickey }
1698a472b3eSmickey /*
1708a472b3eSmickey * Generate exponent and normalized mantissa
1718a472b3eSmickey */
1728a472b3eSmickey dst_exponent = 16; /* initialize for normalization */
1738a472b3eSmickey if (srcp1 == 0) {
1748a472b3eSmickey /*
1758a472b3eSmickey * Check word for most significant bit set. Returns
1768a472b3eSmickey * a value in dst_exponent indicating the bit position,
1778a472b3eSmickey * between -1 and 30.
1788a472b3eSmickey */
1798a472b3eSmickey Find_ms_one_bit(srcp2,dst_exponent);
1808a472b3eSmickey /* left justify source, with msb at bit position 1 */
1818a472b3eSmickey if (dst_exponent >= 0) {
1828a472b3eSmickey srcp1 = srcp2 << dst_exponent;
1838a472b3eSmickey srcp2 = 0;
1848a472b3eSmickey }
1858a472b3eSmickey else {
1868a472b3eSmickey srcp1 = srcp2 >> 1;
1878a472b3eSmickey srcp2 <<= 31;
1888a472b3eSmickey }
1898a472b3eSmickey /*
1908a472b3eSmickey * since msb set is in second word, need to
1918a472b3eSmickey * adjust bit position count
1928a472b3eSmickey */
1938a472b3eSmickey dst_exponent += 32;
1948a472b3eSmickey }
1958a472b3eSmickey else {
1968a472b3eSmickey /*
1978a472b3eSmickey * Check word for most significant bit set. Returns
1988a472b3eSmickey * a value in dst_exponent indicating the bit position,
1998a472b3eSmickey * between -1 and 30.
2008a472b3eSmickey *
2018a472b3eSmickey */
2028a472b3eSmickey Find_ms_one_bit(srcp1,dst_exponent);
2038a472b3eSmickey /* left justify source, with msb at bit position 1 */
2048a472b3eSmickey if (dst_exponent > 0) {
2058a472b3eSmickey Variable_shift_double(srcp1,srcp2,(32-dst_exponent),
2068a472b3eSmickey srcp1);
2078a472b3eSmickey srcp2 <<= dst_exponent;
2088a472b3eSmickey }
2098a472b3eSmickey /*
2108a472b3eSmickey * If dst_exponent = 0, we don't need to shift anything.
2118a472b3eSmickey * If dst_exponent = -1, src = - 2**63 so we won't need to
2128a472b3eSmickey * shift srcp2.
2138a472b3eSmickey */
2148a472b3eSmickey else srcp1 >>= -(dst_exponent);
2158a472b3eSmickey }
216b94afd46Smickey Sgl_set_mantissa(result, (srcp1 >> (SGL_EXP_LENGTH - 1)));
2178a472b3eSmickey Sgl_set_exponent(result, (62+SGL_BIAS) - dst_exponent);
2188a472b3eSmickey
2198a472b3eSmickey /* check for inexact */
2208a472b3eSmickey if (Dint_isinexact_to_sgl(srcp1,srcp2)) {
2218a472b3eSmickey switch (Rounding_mode()) {
2228a472b3eSmickey case ROUNDPLUS:
2238a472b3eSmickey if (Sgl_iszero_sign(result))
2248a472b3eSmickey Sgl_increment(result);
2258a472b3eSmickey break;
2268a472b3eSmickey case ROUNDMINUS:
2278a472b3eSmickey if (Sgl_isone_sign(result))
2288a472b3eSmickey Sgl_increment(result);
2298a472b3eSmickey break;
2308a472b3eSmickey case ROUNDNEAREST:
2318a472b3eSmickey Sgl_roundnearest_from_dint(srcp1,srcp2,result);
2328a472b3eSmickey }
2338a472b3eSmickey if (Is_inexacttrap_enabled()) {
2348a472b3eSmickey *dstptr = result;
2358a472b3eSmickey return(INEXACTEXCEPTION);
2368a472b3eSmickey }
2378a472b3eSmickey else Set_inexactflag();
2388a472b3eSmickey }
2398a472b3eSmickey *dstptr = result;
2408a472b3eSmickey return(NOEXCEPTION);
2418a472b3eSmickey }
2428a472b3eSmickey
2438a472b3eSmickey /*
2448a472b3eSmickey * Double Fixed-point to Double Floating-point
2458a472b3eSmickey */
246b94afd46Smickey int
dbl_to_dbl_fcnvxf(srcptr,null,dstptr,status)247*7eec34daSmickey dbl_to_dbl_fcnvxf(srcptr, null, dstptr, status)
248*7eec34daSmickey dbl_integer *srcptr, *null;
2498a472b3eSmickey dbl_floating_point *dstptr;
250b94afd46Smickey unsigned int *status;
2518a472b3eSmickey {
2528a472b3eSmickey register int srcp1, dst_exponent;
2538a472b3eSmickey register unsigned int srcp2, resultp1 = 0, resultp2 = 0;
2548a472b3eSmickey
2558a472b3eSmickey Dint_copyfromptr(srcptr,srcp1,srcp2);
2568a472b3eSmickey /*
2578a472b3eSmickey * set sign bit of result and get magnitude of source
2588a472b3eSmickey */
2598a472b3eSmickey if (srcp1 < 0) {
2608a472b3eSmickey Dbl_setone_sign(resultp1);
2618a472b3eSmickey Dint_negate(srcp1,srcp2);
2628a472b3eSmickey }
2638a472b3eSmickey else {
2648a472b3eSmickey Dbl_setzero_sign(resultp1);
2658a472b3eSmickey /* Check for zero */
2668a472b3eSmickey if (srcp1 == 0 && srcp2 ==0) {
2678a472b3eSmickey Dbl_setzero(resultp1,resultp2);
2688a472b3eSmickey Dbl_copytoptr(resultp1,resultp2,dstptr);
2698a472b3eSmickey return(NOEXCEPTION);
2708a472b3eSmickey }
2718a472b3eSmickey }
2728a472b3eSmickey /*
2738a472b3eSmickey * Generate exponent and normalized mantissa
2748a472b3eSmickey */
2758a472b3eSmickey dst_exponent = 16; /* initialize for normalization */
2768a472b3eSmickey if (srcp1 == 0) {
2778a472b3eSmickey /*
2788a472b3eSmickey * Check word for most significant bit set. Returns
2798a472b3eSmickey * a value in dst_exponent indicating the bit position,
2808a472b3eSmickey * between -1 and 30.
2818a472b3eSmickey */
2828a472b3eSmickey Find_ms_one_bit(srcp2,dst_exponent);
2838a472b3eSmickey /* left justify source, with msb at bit position 1 */
2848a472b3eSmickey if (dst_exponent >= 0) {
2858a472b3eSmickey srcp1 = srcp2 << dst_exponent;
2868a472b3eSmickey srcp2 = 0;
2878a472b3eSmickey }
2888a472b3eSmickey else {
2898a472b3eSmickey srcp1 = srcp2 >> 1;
2908a472b3eSmickey srcp2 <<= 31;
2918a472b3eSmickey }
2928a472b3eSmickey /*
2938a472b3eSmickey * since msb set is in second word, need to
2948a472b3eSmickey * adjust bit position count
2958a472b3eSmickey */
2968a472b3eSmickey dst_exponent += 32;
2978a472b3eSmickey }
2988a472b3eSmickey else {
2998a472b3eSmickey /*
3008a472b3eSmickey * Check word for most significant bit set. Returns
3018a472b3eSmickey * a value in dst_exponent indicating the bit position,
3028a472b3eSmickey * between -1 and 30.
3038a472b3eSmickey */
3048a472b3eSmickey Find_ms_one_bit(srcp1,dst_exponent);
3058a472b3eSmickey /* left justify source, with msb at bit position 1 */
3068a472b3eSmickey if (dst_exponent > 0) {
3078a472b3eSmickey Variable_shift_double(srcp1,srcp2,(32-dst_exponent),
3088a472b3eSmickey srcp1);
3098a472b3eSmickey srcp2 <<= dst_exponent;
3108a472b3eSmickey }
3118a472b3eSmickey /*
3128a472b3eSmickey * If dst_exponent = 0, we don't need to shift anything.
3138a472b3eSmickey * If dst_exponent = -1, src = - 2**63 so we won't need to
3148a472b3eSmickey * shift srcp2.
3158a472b3eSmickey */
3168a472b3eSmickey else srcp1 >>= -(dst_exponent);
3178a472b3eSmickey }
3188a472b3eSmickey Dbl_set_mantissap1(resultp1, srcp1 >> (DBL_EXP_LENGTH-1));
3198a472b3eSmickey Shiftdouble(srcp1,srcp2,DBL_EXP_LENGTH-1,resultp2);
3208a472b3eSmickey Dbl_set_exponent(resultp1, (62+DBL_BIAS) - dst_exponent);
3218a472b3eSmickey
3228a472b3eSmickey /* check for inexact */
3238a472b3eSmickey if (Dint_isinexact_to_dbl(srcp2)) {
3248a472b3eSmickey switch (Rounding_mode()) {
3258a472b3eSmickey case ROUNDPLUS:
3268a472b3eSmickey if (Dbl_iszero_sign(resultp1)) {
3278a472b3eSmickey Dbl_increment(resultp1,resultp2);
3288a472b3eSmickey }
3298a472b3eSmickey break;
3308a472b3eSmickey case ROUNDMINUS:
3318a472b3eSmickey if (Dbl_isone_sign(resultp1)) {
3328a472b3eSmickey Dbl_increment(resultp1,resultp2);
3338a472b3eSmickey }
3348a472b3eSmickey break;
3358a472b3eSmickey case ROUNDNEAREST:
3368a472b3eSmickey Dbl_roundnearest_from_dint(srcp2,resultp1,
3378a472b3eSmickey resultp2);
3388a472b3eSmickey }
3398a472b3eSmickey if (Is_inexacttrap_enabled()) {
3408a472b3eSmickey Dbl_copytoptr(resultp1,resultp2,dstptr);
3418a472b3eSmickey return(INEXACTEXCEPTION);
3428a472b3eSmickey }
3438a472b3eSmickey else Set_inexactflag();
3448a472b3eSmickey }
3458a472b3eSmickey Dbl_copytoptr(resultp1,resultp2,dstptr);
3468a472b3eSmickey return(NOEXCEPTION);
3478a472b3eSmickey }
348