1 /* $NetBSD: fcnvfxt.c,v 1.3 2005/12/11 12:17:40 christos Exp $ */ 2 3 /* $OpenBSD: fcnvfxt.c,v 1.5 2001/03/29 03:58:18 mickey 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.3 2005/12/11 12:17:40 christos 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(srcptr,dstptr,status) 59 60 sgl_floating_point *srcptr; 61 int *dstptr; 62 unsigned int *status; 63 { 64 register unsigned int src, temp; 65 register int src_exponent, result; 66 67 src = *srcptr; 68 src_exponent = Sgl_exponent(src) - SGL_BIAS; 69 70 /* 71 * Test for overflow 72 */ 73 if (src_exponent > SGL_FX_MAX_EXP) { 74 /* check for MININT */ 75 if ((src_exponent > SGL_FX_MAX_EXP + 1) || 76 Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) { 77 /* 78 * Since source is a number which cannot be 79 * represented in fixed-point format, return 80 * largest (or smallest) fixed-point number. 81 */ 82 Sgl_return_overflow(src,dstptr); 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(srcptr,dstptr,status) 120 121 sgl_floating_point *srcptr; 122 dbl_integer *dstptr; 123 unsigned int *status; 124 { 125 register int src_exponent, resultp1; 126 register unsigned int src, temp, resultp2; 127 128 src = *srcptr; 129 src_exponent = Sgl_exponent(src) - SGL_BIAS; 130 131 /* 132 * Test for overflow 133 */ 134 if (src_exponent > DBL_FX_MAX_EXP) { 135 /* check for MININT */ 136 if ((src_exponent > DBL_FX_MAX_EXP + 1) || 137 Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) { 138 /* 139 * Since source is a number which cannot be 140 * represented in fixed-point format, return 141 * largest (or smallest) fixed-point number. 142 */ 143 Sgl_return_overflow_dbl(src,dstptr); 144 } 145 Dint_set_minint(resultp1,resultp2); 146 Dint_copytoptr(resultp1,resultp2,dstptr); 147 return(NOEXCEPTION); 148 } 149 /* 150 * Generate result 151 */ 152 if (src_exponent >= 0) { 153 temp = src; 154 Sgl_clear_signexponent_set_hidden(temp); 155 Dint_from_sgl_mantissa(temp,src_exponent,resultp1,resultp2); 156 if (Sgl_isone_sign(src)) { 157 Dint_setone_sign(resultp1,resultp2); 158 } 159 Dint_copytoptr(resultp1,resultp2,dstptr); 160 161 /* check for inexact */ 162 if (Sgl_isinexact_to_fix(src,src_exponent)) { 163 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 164 else Set_inexactflag(); 165 } 166 } 167 else { 168 Dint_setzero(resultp1,resultp2); 169 Dint_copytoptr(resultp1,resultp2,dstptr); 170 171 /* check for inexact */ 172 if (Sgl_isnotzero_exponentmantissa(src)) { 173 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 174 else Set_inexactflag(); 175 } 176 } 177 return(NOEXCEPTION); 178 } 179 180 /* 181 * Double Floating-point to Single Fixed-point 182 */ 183 /*ARGSUSED*/ 184 int 185 dbl_to_sgl_fcnvfxt(srcptr,dstptr,status) 186 187 dbl_floating_point *srcptr; 188 int *dstptr; 189 unsigned int *status; 190 { 191 register unsigned int srcp1, srcp2, tempp1, tempp2; 192 register int src_exponent, result; 193 194 Dbl_copyfromptr(srcptr,srcp1,srcp2); 195 src_exponent = Dbl_exponent(srcp1) - DBL_BIAS; 196 197 /* 198 * Test for overflow 199 */ 200 if (src_exponent > SGL_FX_MAX_EXP) { 201 /* check for MININT */ 202 if (Dbl_isoverflow_to_int(src_exponent,srcp1,srcp2)) { 203 Dbl_return_overflow(srcp1,srcp2,dstptr); 204 } 205 } 206 /* 207 * Generate result 208 */ 209 if (src_exponent >= 0) { 210 tempp1 = srcp1; 211 tempp2 = srcp2; 212 Dbl_clear_signexponent_set_hidden(tempp1); 213 Int_from_dbl_mantissa(tempp1,tempp2,src_exponent); 214 if (Dbl_isone_sign(srcp1) && (src_exponent <= SGL_FX_MAX_EXP)) 215 result = -Dbl_allp1(tempp1); 216 else result = Dbl_allp1(tempp1); 217 *dstptr = result; 218 219 /* check for inexact */ 220 if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) { 221 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 222 else Set_inexactflag(); 223 } 224 } 225 else { 226 *dstptr = 0; 227 228 /* check for inexact */ 229 if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) { 230 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 231 else Set_inexactflag(); 232 } 233 } 234 return(NOEXCEPTION); 235 } 236 237 /* 238 * Double Floating-point to Double Fixed-point 239 */ 240 /*ARGSUSED*/ 241 int 242 dbl_to_dbl_fcnvfxt(srcptr,dstptr,status) 243 244 dbl_floating_point *srcptr; 245 dbl_integer *dstptr; 246 unsigned int *status; 247 { 248 register int src_exponent, resultp1; 249 register unsigned int srcp1, srcp2, tempp1, tempp2, resultp2; 250 251 Dbl_copyfromptr(srcptr,srcp1,srcp2); 252 src_exponent = Dbl_exponent(srcp1) - DBL_BIAS; 253 254 /* 255 * Test for overflow 256 */ 257 if (src_exponent > DBL_FX_MAX_EXP) { 258 /* check for MININT */ 259 if ((src_exponent > DBL_FX_MAX_EXP + 1) || 260 Dbl_isnotzero_mantissa(srcp1,srcp2) || Dbl_iszero_sign(srcp1)) { 261 /* 262 * Since source is a number which cannot be 263 * represented in fixed-point format, return 264 * largest (or smallest) fixed-point number. 265 */ 266 Dbl_return_overflow_dbl(srcp1,srcp2,dstptr); 267 } 268 } 269 /* 270 * Generate result 271 */ 272 if (src_exponent >= 0) { 273 tempp1 = srcp1; 274 tempp2 = srcp2; 275 Dbl_clear_signexponent_set_hidden(tempp1); 276 Dint_from_dbl_mantissa(tempp1,tempp2,src_exponent, 277 resultp1,resultp2); 278 if (Dbl_isone_sign(srcp1)) { 279 Dint_setone_sign(resultp1,resultp2); 280 } 281 Dint_copytoptr(resultp1,resultp2,dstptr); 282 283 /* check for inexact */ 284 if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) { 285 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 286 else Set_inexactflag(); 287 } 288 } 289 else { 290 Dint_setzero(resultp1,resultp2); 291 Dint_copytoptr(resultp1,resultp2,dstptr); 292 293 /* check for inexact */ 294 if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) { 295 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 296 else Set_inexactflag(); 297 } 298 } 299 return(NOEXCEPTION); 300 } 301