1 /* $NetBSD: fcnvfxt.c,v 1.5 2012/02/04 17:03:09 skrll Exp $ */ 2 3 /* $OpenBSD: fcnvfxt.c,v 1.8 2010/07/30 18:05:23 kettenis Exp $ */ 4 5 /* 6 * Copyright 1996 1995 by Open Software Foundation, Inc. 7 * All Rights Reserved 8 * 9 * Permission to use, copy, modify, and distribute this software and 10 * its documentation for any purpose and without fee is hereby granted, 11 * provided that the above copyright notice appears in all copies and 12 * that both the copyright notice and this permission notice appear in 13 * supporting documentation. 14 * 15 * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 17 * FOR A PARTICULAR PURPOSE. 18 * 19 * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 21 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 22 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 23 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 24 * 25 */ 26 /* 27 * pmk1.1 28 */ 29 /* 30 * (c) Copyright 1986 HEWLETT-PACKARD COMPANY 31 * 32 * To anyone who acknowledges that this file is provided "AS IS" 33 * without any express or implied warranty: 34 * permission to use, copy, modify, and distribute this file 35 * for any purpose is hereby granted without fee, provided that 36 * the above copyright notice and this notice appears in all 37 * copies, and that the name of Hewlett-Packard Company not be 38 * used in advertising or publicity pertaining to distribution 39 * of the software without specific, written prior permission. 40 * Hewlett-Packard Company makes no representations about the 41 * suitability of this software for any purpose. 42 */ 43 44 #include <sys/cdefs.h> 45 __KERNEL_RCSID(0, "$NetBSD: fcnvfxt.c,v 1.5 2012/02/04 17:03:09 skrll Exp $"); 46 47 #include "../spmath/float.h" 48 #include "../spmath/sgl_float.h" 49 #include "../spmath/dbl_float.h" 50 #include "../spmath/cnv_float.h" 51 52 /* 53 * Convert single floating-point to single fixed-point format 54 * with truncated result 55 */ 56 /*ARGSUSED*/ 57 int 58 sgl_to_sgl_fcnvfxt(sgl_floating_point *srcptr, int *dstptr, 59 unsigned int *status) 60 { 61 register unsigned int src, temp; 62 register int src_exponent, result; 63 64 src = *srcptr; 65 src_exponent = Sgl_exponent(src) - SGL_BIAS; 66 67 /* 68 * Test for overflow 69 */ 70 if (src_exponent > SGL_FX_MAX_EXP) { 71 /* check for MININT */ 72 if ((src_exponent > SGL_FX_MAX_EXP + 1) || 73 Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) { 74 if (Sgl_iszero_sign(src)) result = 0x7fffffff; 75 else result = 0x80000000; 76 77 if (Is_invalidtrap_enabled()) { 78 return(INVALIDEXCEPTION); 79 } 80 Set_invalidflag(); 81 *dstptr = result; 82 return(NOEXCEPTION); 83 } 84 } 85 /* 86 * Generate result 87 */ 88 if (src_exponent >= 0) { 89 temp = src; 90 Sgl_clear_signexponent_set_hidden(temp); 91 Int_from_sgl_mantissa(temp,src_exponent); 92 if (Sgl_isone_sign(src)) result = -Sgl_all(temp); 93 else result = Sgl_all(temp); 94 *dstptr = result; 95 96 /* check for inexact */ 97 if (Sgl_isinexact_to_fix(src,src_exponent)) { 98 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 99 else Set_inexactflag(); 100 } 101 } 102 else { 103 *dstptr = 0; 104 105 /* check for inexact */ 106 if (Sgl_isnotzero_exponentmantissa(src)) { 107 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 108 else Set_inexactflag(); 109 } 110 } 111 return(NOEXCEPTION); 112 } 113 114 /* 115 * Single Floating-point to Double Fixed-point 116 */ 117 /*ARGSUSED*/ 118 int 119 sgl_to_dbl_fcnvfxt(sgl_floating_point *srcptr, dbl_integer *dstptr, 120 unsigned int *status) 121 { 122 register int src_exponent, resultp1; 123 register unsigned int src, temp, resultp2; 124 125 src = *srcptr; 126 src_exponent = Sgl_exponent(src) - SGL_BIAS; 127 128 /* 129 * Test for overflow 130 */ 131 if (src_exponent > DBL_FX_MAX_EXP) { 132 /* check for MININT */ 133 if ((src_exponent > DBL_FX_MAX_EXP + 1) || 134 Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) { 135 if (Sgl_iszero_sign(src)) { 136 resultp1 = 0x7fffffff; 137 resultp2 = 0xffffffff; 138 } 139 else { 140 resultp1 = 0x80000000; 141 resultp2 = 0; 142 } 143 144 if (Is_invalidtrap_enabled()) { 145 return(INVALIDEXCEPTION); 146 } 147 Set_invalidflag(); 148 Dint_copytoptr(resultp1,resultp2,dstptr); 149 return(NOEXCEPTION); 150 } 151 Dint_set_minint(resultp1,resultp2); 152 Dint_copytoptr(resultp1,resultp2,dstptr); 153 return(NOEXCEPTION); 154 } 155 /* 156 * Generate result 157 */ 158 if (src_exponent >= 0) { 159 temp = src; 160 Sgl_clear_signexponent_set_hidden(temp); 161 Dint_from_sgl_mantissa(temp,src_exponent,resultp1,resultp2); 162 if (Sgl_isone_sign(src)) { 163 Dint_setone_sign(resultp1,resultp2); 164 } 165 Dint_copytoptr(resultp1,resultp2,dstptr); 166 167 /* check for inexact */ 168 if (Sgl_isinexact_to_fix(src,src_exponent)) { 169 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 170 else Set_inexactflag(); 171 } 172 } 173 else { 174 Dint_setzero(resultp1,resultp2); 175 Dint_copytoptr(resultp1,resultp2,dstptr); 176 177 /* check for inexact */ 178 if (Sgl_isnotzero_exponentmantissa(src)) { 179 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 180 else Set_inexactflag(); 181 } 182 } 183 return(NOEXCEPTION); 184 } 185 186 /* 187 * Double Floating-point to Single Fixed-point 188 */ 189 /*ARGSUSED*/ 190 int 191 dbl_to_sgl_fcnvfxt(dbl_floating_point *srcptr, int *dstptr, 192 unsigned int *status) 193 { 194 register unsigned int srcp1, srcp2, tempp1, tempp2; 195 register int src_exponent, result; 196 197 Dbl_copyfromptr(srcptr,srcp1,srcp2); 198 src_exponent = Dbl_exponent(srcp1) - DBL_BIAS; 199 200 /* 201 * Test for overflow 202 */ 203 if (src_exponent > SGL_FX_MAX_EXP) { 204 /* check for MININT */ 205 if (Dbl_isoverflow_to_int(src_exponent,srcp1,srcp2)) { 206 if (Dbl_iszero_sign(srcp1)) result = 0x7fffffff; 207 else result = 0x80000000; 208 209 if (Is_invalidtrap_enabled()) { 210 return(INVALIDEXCEPTION); 211 } 212 Set_invalidflag(); 213 *dstptr = result; 214 return(NOEXCEPTION); 215 } 216 } 217 /* 218 * Generate result 219 */ 220 if (src_exponent >= 0) { 221 tempp1 = srcp1; 222 tempp2 = srcp2; 223 Dbl_clear_signexponent_set_hidden(tempp1); 224 Int_from_dbl_mantissa(tempp1,tempp2,src_exponent); 225 if (Dbl_isone_sign(srcp1) && (src_exponent <= SGL_FX_MAX_EXP)) 226 result = -Dbl_allp1(tempp1); 227 else result = Dbl_allp1(tempp1); 228 *dstptr = result; 229 230 /* check for inexact */ 231 if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) { 232 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 233 else Set_inexactflag(); 234 } 235 } 236 else { 237 *dstptr = 0; 238 239 /* check for inexact */ 240 if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) { 241 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 242 else Set_inexactflag(); 243 } 244 } 245 return(NOEXCEPTION); 246 } 247 248 /* 249 * Double Floating-point to Double Fixed-point 250 */ 251 /*ARGSUSED*/ 252 int 253 dbl_to_dbl_fcnvfxt(dbl_floating_point *srcptr, dbl_integer *dstptr, 254 unsigned int *status) 255 { 256 register int src_exponent, resultp1; 257 register unsigned int srcp1, srcp2, tempp1, tempp2, resultp2; 258 259 Dbl_copyfromptr(srcptr,srcp1,srcp2); 260 src_exponent = Dbl_exponent(srcp1) - DBL_BIAS; 261 262 /* 263 * Test for overflow 264 */ 265 if (src_exponent > DBL_FX_MAX_EXP) { 266 /* check for MININT */ 267 if ((src_exponent > DBL_FX_MAX_EXP + 1) || 268 Dbl_isnotzero_mantissa(srcp1,srcp2) || Dbl_iszero_sign(srcp1)) { 269 if (Dbl_iszero_sign(srcp1)) { 270 resultp1 = 0x7fffffff; 271 resultp2 = 0xffffffff; 272 } 273 else { 274 resultp1 = 0x80000000; 275 resultp2 = 0; 276 } 277 278 if (Is_invalidtrap_enabled()) { 279 return(INVALIDEXCEPTION); 280 } 281 Set_invalidflag(); 282 Dint_copytoptr(resultp1,resultp2,dstptr); 283 return(NOEXCEPTION); 284 } 285 } 286 /* 287 * Generate result 288 */ 289 if (src_exponent >= 0) { 290 tempp1 = srcp1; 291 tempp2 = srcp2; 292 Dbl_clear_signexponent_set_hidden(tempp1); 293 Dint_from_dbl_mantissa(tempp1,tempp2,src_exponent, 294 resultp1,resultp2); 295 if (Dbl_isone_sign(srcp1)) { 296 Dint_setone_sign(resultp1,resultp2); 297 } 298 Dint_copytoptr(resultp1,resultp2,dstptr); 299 300 /* check for inexact */ 301 if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) { 302 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 303 else Set_inexactflag(); 304 } 305 } 306 else { 307 Dint_setzero(resultp1,resultp2); 308 Dint_copytoptr(resultp1,resultp2,dstptr); 309 310 /* check for inexact */ 311 if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) { 312 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 313 else Set_inexactflag(); 314 } 315 } 316 return(NOEXCEPTION); 317 } 318