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