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