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/fcnvfut.c $Revision: 1.1 $ 13 * 14 * Purpose: 15 * Floating-point to Unsigned Fixed-point Converts with Truncation 16 * 17 * External Interfaces: 18 * dbl_to_dbl_fcnvfut(srcptr,nullptr,dstptr,status) 19 * dbl_to_sgl_fcnvfut(srcptr,nullptr,dstptr,status) 20 * sgl_to_dbl_fcnvfut(srcptr,nullptr,dstptr,status) 21 * sgl_to_sgl_fcnvfut(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 * Floating-point to Unsigned Fixed-point Converts with Truncation * 39 ************************************************************************/ 40 41 /* 42 * Convert single floating-point to single fixed-point format 43 * with truncated result 44 */ 45 /*ARGSUSED*/ 46 int 47 sgl_to_sgl_fcnvfut (sgl_floating_point * srcptr, unsigned int *nullptr, 48 unsigned int *dstptr, unsigned int *status) 49 { 50 register unsigned int src, result; 51 register int src_exponent; 52 53 src = *srcptr; 54 src_exponent = Sgl_exponent(src) - SGL_BIAS; 55 56 /* 57 * Test for overflow 58 */ 59 if (src_exponent > SGL_FX_MAX_EXP + 1) { 60 if (Sgl_isone_sign(src)) { 61 result = 0; 62 } else { 63 result = 0xffffffff; 64 } 65 if (Is_invalidtrap_enabled()) { 66 return(INVALIDEXCEPTION); 67 } 68 Set_invalidflag(); 69 *dstptr = result; 70 return(NOEXCEPTION); 71 } 72 /* 73 * Generate result 74 */ 75 if (src_exponent >= 0) { 76 /* 77 * Check sign. 78 * If negative, trap unimplemented. 79 */ 80 if (Sgl_isone_sign(src)) { 81 result = 0; 82 if (Is_invalidtrap_enabled()) { 83 return(INVALIDEXCEPTION); 84 } 85 Set_invalidflag(); 86 *dstptr = result; 87 return(NOEXCEPTION); 88 } 89 Sgl_clear_signexponent_set_hidden(src); 90 Suint_from_sgl_mantissa(src,src_exponent,result); 91 *dstptr = result; 92 93 /* check for inexact */ 94 if (Sgl_isinexact_to_unsigned(src,src_exponent)) { 95 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 96 else Set_inexactflag(); 97 } 98 } 99 else { 100 *dstptr = 0; 101 102 /* check for inexact */ 103 if (Sgl_isnotzero_exponentmantissa(src)) { 104 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 105 else Set_inexactflag(); 106 } 107 } 108 return(NOEXCEPTION); 109 } 110 111 /* 112 * Single Floating-point to Double Unsigned Fixed 113 */ 114 /*ARGSUSED*/ 115 int 116 sgl_to_dbl_fcnvfut (sgl_floating_point * srcptr, unsigned int *nullptr, 117 dbl_unsigned * dstptr, unsigned int *status) 118 { 119 register int src_exponent; 120 register unsigned int src, resultp1, resultp2; 121 122 src = *srcptr; 123 src_exponent = Sgl_exponent(src) - SGL_BIAS; 124 125 /* 126 * Test for overflow 127 */ 128 if (src_exponent > DBL_FX_MAX_EXP + 1) { 129 if (Sgl_isone_sign(src)) { 130 resultp1 = resultp2 = 0; 131 } else { 132 resultp1 = resultp2 = 0xffffffff; 133 } 134 if (Is_invalidtrap_enabled()) { 135 return(INVALIDEXCEPTION); 136 } 137 Set_invalidflag(); 138 Duint_copytoptr(resultp1,resultp2,dstptr); 139 return(NOEXCEPTION); 140 } 141 /* 142 * Generate result 143 */ 144 if (src_exponent >= 0) { 145 /* 146 * Check sign. 147 * If negative, trap unimplemented. 148 */ 149 if (Sgl_isone_sign(src)) { 150 resultp1 = resultp2 = 0; 151 if (Is_invalidtrap_enabled()) { 152 return(INVALIDEXCEPTION); 153 } 154 Set_invalidflag(); 155 Duint_copytoptr(resultp1,resultp2,dstptr); 156 return(NOEXCEPTION); 157 } 158 Sgl_clear_signexponent_set_hidden(src); 159 Duint_from_sgl_mantissa(src,src_exponent,resultp1,resultp2); 160 Duint_copytoptr(resultp1,resultp2,dstptr); 161 162 /* check for inexact */ 163 if (Sgl_isinexact_to_unsigned(src,src_exponent)) { 164 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 165 else Set_inexactflag(); 166 } 167 } 168 else { 169 Duint_setzero(resultp1,resultp2); 170 Duint_copytoptr(resultp1,resultp2,dstptr); 171 172 /* check for inexact */ 173 if (Sgl_isnotzero_exponentmantissa(src)) { 174 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 175 else Set_inexactflag(); 176 } 177 } 178 return(NOEXCEPTION); 179 } 180 181 /* 182 * Double Floating-point to Single Unsigned Fixed 183 */ 184 /*ARGSUSED*/ 185 int 186 dbl_to_sgl_fcnvfut (dbl_floating_point * srcptr, unsigned int *nullptr, 187 unsigned int *dstptr, unsigned int *status) 188 { 189 register unsigned int srcp1, srcp2, result; 190 register int src_exponent; 191 192 Dbl_copyfromptr(srcptr,srcp1,srcp2); 193 src_exponent = Dbl_exponent(srcp1) - DBL_BIAS; 194 195 /* 196 * Test for overflow 197 */ 198 if (src_exponent > SGL_FX_MAX_EXP + 1) { 199 if (Dbl_isone_sign(srcp1)) { 200 result = 0; 201 } else { 202 result = 0xffffffff; 203 } 204 if (Is_invalidtrap_enabled()) { 205 return(INVALIDEXCEPTION); 206 } 207 Set_invalidflag(); 208 *dstptr = result; 209 return(NOEXCEPTION); 210 } 211 /* 212 * Generate result 213 */ 214 if (src_exponent >= 0) { 215 /* 216 * Check sign. 217 * If negative, trap unimplemented. 218 */ 219 if (Dbl_isone_sign(srcp1)) { 220 result = 0; 221 if (Is_invalidtrap_enabled()) { 222 return(INVALIDEXCEPTION); 223 } 224 Set_invalidflag(); 225 *dstptr = result; 226 return(NOEXCEPTION); 227 } 228 Dbl_clear_signexponent_set_hidden(srcp1); 229 Suint_from_dbl_mantissa(srcp1,srcp2,src_exponent,result); 230 *dstptr = result; 231 232 /* check for inexact */ 233 if (Dbl_isinexact_to_unsigned(srcp1,srcp2,src_exponent)) { 234 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 235 else Set_inexactflag(); 236 } 237 } 238 else { 239 *dstptr = 0; 240 241 /* check for inexact */ 242 if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) { 243 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 244 else Set_inexactflag(); 245 } 246 } 247 return(NOEXCEPTION); 248 } 249 250 /* 251 * Double Floating-point to Double Unsigned Fixed 252 */ 253 /*ARGSUSED*/ 254 int 255 dbl_to_dbl_fcnvfut (dbl_floating_point * srcptr, unsigned int *nullptr, 256 dbl_unsigned * dstptr, unsigned int *status) 257 { 258 register int src_exponent; 259 register unsigned int srcp1, srcp2, resultp1, resultp2; 260 261 Dbl_copyfromptr(srcptr,srcp1,srcp2); 262 src_exponent = Dbl_exponent(srcp1) - DBL_BIAS; 263 264 /* 265 * Test for overflow 266 */ 267 if (src_exponent > DBL_FX_MAX_EXP + 1) { 268 if (Dbl_isone_sign(srcp1)) { 269 resultp1 = resultp2 = 0; 270 } else { 271 resultp1 = resultp2 = 0xffffffff; 272 } 273 if (Is_invalidtrap_enabled()) { 274 return(INVALIDEXCEPTION); 275 } 276 Set_invalidflag(); 277 Duint_copytoptr(resultp1,resultp2,dstptr); 278 return(NOEXCEPTION); 279 } 280 /* 281 * Generate result 282 */ 283 if (src_exponent >= 0) { 284 /* 285 * Check sign. 286 * If negative, trap unimplemented. 287 */ 288 if (Dbl_isone_sign(srcp1)) { 289 resultp1 = resultp2 = 0; 290 if (Is_invalidtrap_enabled()) { 291 return(INVALIDEXCEPTION); 292 } 293 Set_invalidflag(); 294 Duint_copytoptr(resultp1,resultp2,dstptr); 295 return(NOEXCEPTION); 296 } 297 Dbl_clear_signexponent_set_hidden(srcp1); 298 Duint_from_dbl_mantissa(srcp1,srcp2,src_exponent, 299 resultp1,resultp2); 300 Duint_copytoptr(resultp1,resultp2,dstptr); 301 302 /* check for inexact */ 303 if (Dbl_isinexact_to_unsigned(srcp1,srcp2,src_exponent)) { 304 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 305 else Set_inexactflag(); 306 } 307 } 308 else { 309 Duint_setzero(resultp1,resultp2); 310 Duint_copytoptr(resultp1,resultp2,dstptr); 311 312 /* check for inexact */ 313 if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) { 314 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 315 else Set_inexactflag(); 316 } 317 } 318 return(NOEXCEPTION); 319 } 320