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