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 45 int 46 sgl_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 104 int 105 sgl_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 145 int 146 dbl_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 227 int 228 dbl_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 306