1 /* 2 * Linux/PA-RISC Project (http://www.parisc-linux.org/) 3 * 4 * Floating-point emulation code 5 * Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2, or (at your option) 10 * any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 */ 21 /* 22 * BEGIN_DESC 23 * 24 * File: 25 * @(#) pa/spmath/fcnvfxt.c $Revision: 1.1 $ 26 * 27 * Purpose: 28 * Single Floating-point to Single Fixed-point /w truncated result 29 * Single Floating-point to Double Fixed-point /w truncated result 30 * Double Floating-point to Single Fixed-point /w truncated result 31 * Double Floating-point to Double Fixed-point /w truncated result 32 * 33 * External Interfaces: 34 * dbl_to_dbl_fcnvfxt(srcptr,nullptr,dstptr,status) 35 * dbl_to_sgl_fcnvfxt(srcptr,nullptr,dstptr,status) 36 * sgl_to_dbl_fcnvfxt(srcptr,nullptr,dstptr,status) 37 * sgl_to_sgl_fcnvfxt(srcptr,nullptr,dstptr,status) 38 * 39 * Internal Interfaces: 40 * 41 * Theory: 42 * <<please update with a overview of the operation of this file>> 43 * 44 * END_DESC 45 */ 46 47 48 #include "float.h" 49 #include "sgl_float.h" 50 #include "dbl_float.h" 51 #include "cnv_float.h" 52 53 /* 54 * Convert single floating-point to single fixed-point format 55 * with truncated result 56 */ 57 /*ARGSUSED*/ 58 int 59 sgl_to_sgl_fcnvfxt( 60 sgl_floating_point *srcptr, 61 unsigned int *nullptr, 62 int *dstptr, 63 unsigned int *status) 64 { 65 register unsigned int src, temp; 66 register int src_exponent, result; 67 68 src = *srcptr; 69 src_exponent = Sgl_exponent(src) - SGL_BIAS; 70 71 /* 72 * Test for overflow 73 */ 74 if (src_exponent > SGL_FX_MAX_EXP) { 75 /* check for MININT */ 76 if ((src_exponent > SGL_FX_MAX_EXP + 1) || 77 Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) { 78 if (Sgl_iszero_sign(src)) result = 0x7fffffff; 79 else result = 0x80000000; 80 81 if (Is_invalidtrap_enabled()) { 82 return(INVALIDEXCEPTION); 83 } 84 Set_invalidflag(); 85 *dstptr = result; 86 return(NOEXCEPTION); 87 } 88 } 89 /* 90 * Generate result 91 */ 92 if (src_exponent >= 0) { 93 temp = src; 94 Sgl_clear_signexponent_set_hidden(temp); 95 Int_from_sgl_mantissa(temp,src_exponent); 96 if (Sgl_isone_sign(src)) result = -Sgl_all(temp); 97 else result = Sgl_all(temp); 98 *dstptr = result; 99 100 /* check for inexact */ 101 if (Sgl_isinexact_to_fix(src,src_exponent)) { 102 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 103 else Set_inexactflag(); 104 } 105 } 106 else { 107 *dstptr = 0; 108 109 /* check for inexact */ 110 if (Sgl_isnotzero_exponentmantissa(src)) { 111 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 112 else Set_inexactflag(); 113 } 114 } 115 return(NOEXCEPTION); 116 } 117 118 /* 119 * Single Floating-point to Double Fixed-point 120 */ 121 /*ARGSUSED*/ 122 int 123 sgl_to_dbl_fcnvfxt( 124 sgl_floating_point *srcptr, 125 unsigned int *nullptr, 126 dbl_integer *dstptr, 127 unsigned int *status) 128 { 129 register int src_exponent, resultp1; 130 register unsigned int src, temp, resultp2; 131 132 src = *srcptr; 133 src_exponent = Sgl_exponent(src) - SGL_BIAS; 134 135 /* 136 * Test for overflow 137 */ 138 if (src_exponent > DBL_FX_MAX_EXP) { 139 /* check for MININT */ 140 if ((src_exponent > DBL_FX_MAX_EXP + 1) || 141 Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) { 142 if (Sgl_iszero_sign(src)) { 143 resultp1 = 0x7fffffff; 144 resultp2 = 0xffffffff; 145 } 146 else { 147 resultp1 = 0x80000000; 148 resultp2 = 0; 149 } 150 if (Is_invalidtrap_enabled()) { 151 return(INVALIDEXCEPTION); 152 } 153 Set_invalidflag(); 154 Dint_copytoptr(resultp1,resultp2,dstptr); 155 return(NOEXCEPTION); 156 } 157 Dint_set_minint(resultp1,resultp2); 158 Dint_copytoptr(resultp1,resultp2,dstptr); 159 return(NOEXCEPTION); 160 } 161 /* 162 * Generate result 163 */ 164 if (src_exponent >= 0) { 165 temp = src; 166 Sgl_clear_signexponent_set_hidden(temp); 167 Dint_from_sgl_mantissa(temp,src_exponent,resultp1,resultp2); 168 if (Sgl_isone_sign(src)) { 169 Dint_setone_sign(resultp1,resultp2); 170 } 171 Dint_copytoptr(resultp1,resultp2,dstptr); 172 173 /* check for inexact */ 174 if (Sgl_isinexact_to_fix(src,src_exponent)) { 175 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 176 else Set_inexactflag(); 177 } 178 } 179 else { 180 Dint_setzero(resultp1,resultp2); 181 Dint_copytoptr(resultp1,resultp2,dstptr); 182 183 /* check for inexact */ 184 if (Sgl_isnotzero_exponentmantissa(src)) { 185 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 186 else Set_inexactflag(); 187 } 188 } 189 return(NOEXCEPTION); 190 } 191 192 /* 193 * Double Floating-point to Single Fixed-point 194 */ 195 /*ARGSUSED*/ 196 int 197 dbl_to_sgl_fcnvfxt( 198 dbl_floating_point *srcptr, 199 unsigned int *nullptr, 200 int *dstptr, 201 unsigned int *status) 202 { 203 register unsigned int srcp1, srcp2, tempp1, tempp2; 204 register int src_exponent, result; 205 206 Dbl_copyfromptr(srcptr,srcp1,srcp2); 207 src_exponent = Dbl_exponent(srcp1) - DBL_BIAS; 208 209 /* 210 * Test for overflow 211 */ 212 if (src_exponent > SGL_FX_MAX_EXP) { 213 /* check for MININT */ 214 if (Dbl_isoverflow_to_int(src_exponent,srcp1,srcp2)) { 215 if (Dbl_iszero_sign(srcp1)) result = 0x7fffffff; 216 else result = 0x80000000; 217 218 if (Is_invalidtrap_enabled()) { 219 return(INVALIDEXCEPTION); 220 } 221 Set_invalidflag(); 222 *dstptr = result; 223 return(NOEXCEPTION); 224 } 225 } 226 /* 227 * Generate result 228 */ 229 if (src_exponent >= 0) { 230 tempp1 = srcp1; 231 tempp2 = srcp2; 232 Dbl_clear_signexponent_set_hidden(tempp1); 233 Int_from_dbl_mantissa(tempp1,tempp2,src_exponent); 234 if (Dbl_isone_sign(srcp1) && (src_exponent <= SGL_FX_MAX_EXP)) 235 result = -Dbl_allp1(tempp1); 236 else result = Dbl_allp1(tempp1); 237 *dstptr = result; 238 239 /* check for inexact */ 240 if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) { 241 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 242 else Set_inexactflag(); 243 } 244 } 245 else { 246 *dstptr = 0; 247 248 /* check for inexact */ 249 if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) { 250 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 251 else Set_inexactflag(); 252 } 253 } 254 return(NOEXCEPTION); 255 } 256 257 /* 258 * Double Floating-point to Double Fixed-point 259 */ 260 /*ARGSUSED*/ 261 int 262 dbl_to_dbl_fcnvfxt( 263 dbl_floating_point *srcptr, 264 unsigned int *nullptr, 265 dbl_integer *dstptr, 266 unsigned int *status) 267 { 268 register int src_exponent, resultp1; 269 register unsigned int srcp1, srcp2, tempp1, tempp2, resultp2; 270 271 Dbl_copyfromptr(srcptr,srcp1,srcp2); 272 src_exponent = Dbl_exponent(srcp1) - DBL_BIAS; 273 274 /* 275 * Test for overflow 276 */ 277 if (src_exponent > DBL_FX_MAX_EXP) { 278 /* check for MININT */ 279 if ((src_exponent > DBL_FX_MAX_EXP + 1) || 280 Dbl_isnotzero_mantissa(srcp1,srcp2) || Dbl_iszero_sign(srcp1)) { 281 if (Dbl_iszero_sign(srcp1)) { 282 resultp1 = 0x7fffffff; 283 resultp2 = 0xffffffff; 284 } 285 else { 286 resultp1 = 0x80000000; 287 resultp2 = 0; 288 } 289 if (Is_invalidtrap_enabled()) { 290 return(INVALIDEXCEPTION); 291 } 292 Set_invalidflag(); 293 Dint_copytoptr(resultp1,resultp2,dstptr); 294 return(NOEXCEPTION); 295 } 296 } 297 /* 298 * Generate result 299 */ 300 if (src_exponent >= 0) { 301 tempp1 = srcp1; 302 tempp2 = srcp2; 303 Dbl_clear_signexponent_set_hidden(tempp1); 304 Dint_from_dbl_mantissa(tempp1,tempp2,src_exponent, 305 resultp1,resultp2); 306 if (Dbl_isone_sign(srcp1)) { 307 Dint_setone_sign(resultp1,resultp2); 308 } 309 Dint_copytoptr(resultp1,resultp2,dstptr); 310 311 /* check for inexact */ 312 if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) { 313 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 314 else Set_inexactflag(); 315 } 316 } 317 else { 318 Dint_setzero(resultp1,resultp2); 319 Dint_copytoptr(resultp1,resultp2,dstptr); 320 321 /* check for inexact */ 322 if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) { 323 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 324 else Set_inexactflag(); 325 } 326 } 327 return(NOEXCEPTION); 328 } 329