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/fcnvfut.c $Revision: 1.1 $ 26 * 27 * Purpose: 28 * Floating-point to Unsigned Fixed-point Converts with Truncation 29 * 30 * External Interfaces: 31 * dbl_to_dbl_fcnvfut(srcptr,nullptr,dstptr,status) 32 * dbl_to_sgl_fcnvfut(srcptr,nullptr,dstptr,status) 33 * sgl_to_dbl_fcnvfut(srcptr,nullptr,dstptr,status) 34 * sgl_to_sgl_fcnvfut(srcptr,nullptr,dstptr,status) 35 * 36 * Internal Interfaces: 37 * 38 * Theory: 39 * <<please update with a overview of the operation of this file>> 40 * 41 * END_DESC 42*/ 43 44 45#include "float.h" 46#include "sgl_float.h" 47#include "dbl_float.h" 48#include "cnv_float.h" 49 50/************************************************************************ 51 * Floating-point to Unsigned Fixed-point Converts with Truncation * 52 ************************************************************************/ 53 54/* 55 * Convert single floating-point to single fixed-point format 56 * with truncated result 57 */ 58/*ARGSUSED*/ 59int 60sgl_to_sgl_fcnvfut (sgl_floating_point * srcptr, unsigned int *nullptr, 61 unsigned int *dstptr, unsigned int *status) 62{ 63 register unsigned int src, result; 64 register int src_exponent; 65 66 src = *srcptr; 67 src_exponent = Sgl_exponent(src) - SGL_BIAS; 68 69 /* 70 * Test for overflow 71 */ 72 if (src_exponent > SGL_FX_MAX_EXP + 1) { 73 if (Sgl_isone_sign(src)) { 74 result = 0; 75 } else { 76 result = 0xffffffff; 77 } 78 if (Is_invalidtrap_enabled()) { 79 return(INVALIDEXCEPTION); 80 } 81 Set_invalidflag(); 82 *dstptr = result; 83 return(NOEXCEPTION); 84 } 85 /* 86 * Generate result 87 */ 88 if (src_exponent >= 0) { 89 /* 90 * Check sign. 91 * If negative, trap unimplemented. 92 */ 93 if (Sgl_isone_sign(src)) { 94 result = 0; 95 if (Is_invalidtrap_enabled()) { 96 return(INVALIDEXCEPTION); 97 } 98 Set_invalidflag(); 99 *dstptr = result; 100 return(NOEXCEPTION); 101 } 102 Sgl_clear_signexponent_set_hidden(src); 103 Suint_from_sgl_mantissa(src,src_exponent,result); 104 *dstptr = result; 105 106 /* check for inexact */ 107 if (Sgl_isinexact_to_unsigned(src,src_exponent)) { 108 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 109 else Set_inexactflag(); 110 } 111 } 112 else { 113 *dstptr = 0; 114 115 /* check for inexact */ 116 if (Sgl_isnotzero_exponentmantissa(src)) { 117 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 118 else Set_inexactflag(); 119 } 120 } 121 return(NOEXCEPTION); 122} 123 124/* 125 * Single Floating-point to Double Unsigned Fixed 126 */ 127/*ARGSUSED*/ 128int 129sgl_to_dbl_fcnvfut (sgl_floating_point * srcptr, unsigned int *nullptr, 130 dbl_unsigned * dstptr, unsigned int *status) 131{ 132 register int src_exponent; 133 register unsigned int src, resultp1, resultp2; 134 135 src = *srcptr; 136 src_exponent = Sgl_exponent(src) - SGL_BIAS; 137 138 /* 139 * Test for overflow 140 */ 141 if (src_exponent > DBL_FX_MAX_EXP + 1) { 142 if (Sgl_isone_sign(src)) { 143 resultp1 = resultp2 = 0; 144 } else { 145 resultp1 = resultp2 = 0xffffffff; 146 } 147 if (Is_invalidtrap_enabled()) { 148 return(INVALIDEXCEPTION); 149 } 150 Set_invalidflag(); 151 Duint_copytoptr(resultp1,resultp2,dstptr); 152 return(NOEXCEPTION); 153 } 154 /* 155 * Generate result 156 */ 157 if (src_exponent >= 0) { 158 /* 159 * Check sign. 160 * If negative, trap unimplemented. 161 */ 162 if (Sgl_isone_sign(src)) { 163 resultp1 = resultp2 = 0; 164 if (Is_invalidtrap_enabled()) { 165 return(INVALIDEXCEPTION); 166 } 167 Set_invalidflag(); 168 Duint_copytoptr(resultp1,resultp2,dstptr); 169 return(NOEXCEPTION); 170 } 171 Sgl_clear_signexponent_set_hidden(src); 172 Duint_from_sgl_mantissa(src,src_exponent,resultp1,resultp2); 173 Duint_copytoptr(resultp1,resultp2,dstptr); 174 175 /* check for inexact */ 176 if (Sgl_isinexact_to_unsigned(src,src_exponent)) { 177 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 178 else Set_inexactflag(); 179 } 180 } 181 else { 182 Duint_setzero(resultp1,resultp2); 183 Duint_copytoptr(resultp1,resultp2,dstptr); 184 185 /* check for inexact */ 186 if (Sgl_isnotzero_exponentmantissa(src)) { 187 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 188 else Set_inexactflag(); 189 } 190 } 191 return(NOEXCEPTION); 192} 193 194/* 195 * Double Floating-point to Single Unsigned Fixed 196 */ 197/*ARGSUSED*/ 198int 199dbl_to_sgl_fcnvfut (dbl_floating_point * srcptr, unsigned int *nullptr, 200 unsigned int *dstptr, unsigned int *status) 201{ 202 register unsigned int srcp1, srcp2, result; 203 register int src_exponent; 204 205 Dbl_copyfromptr(srcptr,srcp1,srcp2); 206 src_exponent = Dbl_exponent(srcp1) - DBL_BIAS; 207 208 /* 209 * Test for overflow 210 */ 211 if (src_exponent > SGL_FX_MAX_EXP + 1) { 212 if (Dbl_isone_sign(srcp1)) { 213 result = 0; 214 } else { 215 result = 0xffffffff; 216 } 217 if (Is_invalidtrap_enabled()) { 218 return(INVALIDEXCEPTION); 219 } 220 Set_invalidflag(); 221 *dstptr = result; 222 return(NOEXCEPTION); 223 } 224 /* 225 * Generate result 226 */ 227 if (src_exponent >= 0) { 228 /* 229 * Check sign. 230 * If negative, trap unimplemented. 231 */ 232 if (Dbl_isone_sign(srcp1)) { 233 result = 0; 234 if (Is_invalidtrap_enabled()) { 235 return(INVALIDEXCEPTION); 236 } 237 Set_invalidflag(); 238 *dstptr = result; 239 return(NOEXCEPTION); 240 } 241 Dbl_clear_signexponent_set_hidden(srcp1); 242 Suint_from_dbl_mantissa(srcp1,srcp2,src_exponent,result); 243 *dstptr = result; 244 245 /* check for inexact */ 246 if (Dbl_isinexact_to_unsigned(srcp1,srcp2,src_exponent)) { 247 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 248 else Set_inexactflag(); 249 } 250 } 251 else { 252 *dstptr = 0; 253 254 /* check for inexact */ 255 if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) { 256 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 257 else Set_inexactflag(); 258 } 259 } 260 return(NOEXCEPTION); 261} 262 263/* 264 * Double Floating-point to Double Unsigned Fixed 265 */ 266/*ARGSUSED*/ 267int 268dbl_to_dbl_fcnvfut (dbl_floating_point * srcptr, unsigned int *nullptr, 269 dbl_unsigned * dstptr, unsigned int *status) 270{ 271 register int src_exponent; 272 register unsigned int srcp1, srcp2, resultp1, resultp2; 273 274 Dbl_copyfromptr(srcptr,srcp1,srcp2); 275 src_exponent = Dbl_exponent(srcp1) - DBL_BIAS; 276 277 /* 278 * Test for overflow 279 */ 280 if (src_exponent > DBL_FX_MAX_EXP + 1) { 281 if (Dbl_isone_sign(srcp1)) { 282 resultp1 = resultp2 = 0; 283 } else { 284 resultp1 = resultp2 = 0xffffffff; 285 } 286 if (Is_invalidtrap_enabled()) { 287 return(INVALIDEXCEPTION); 288 } 289 Set_invalidflag(); 290 Duint_copytoptr(resultp1,resultp2,dstptr); 291 return(NOEXCEPTION); 292 } 293 /* 294 * Generate result 295 */ 296 if (src_exponent >= 0) { 297 /* 298 * Check sign. 299 * If negative, trap unimplemented. 300 */ 301 if (Dbl_isone_sign(srcp1)) { 302 resultp1 = resultp2 = 0; 303 if (Is_invalidtrap_enabled()) { 304 return(INVALIDEXCEPTION); 305 } 306 Set_invalidflag(); 307 Duint_copytoptr(resultp1,resultp2,dstptr); 308 return(NOEXCEPTION); 309 } 310 Dbl_clear_signexponent_set_hidden(srcp1); 311 Duint_from_dbl_mantissa(srcp1,srcp2,src_exponent, 312 resultp1,resultp2); 313 Duint_copytoptr(resultp1,resultp2,dstptr); 314 315 /* check for inexact */ 316 if (Dbl_isinexact_to_unsigned(srcp1,srcp2,src_exponent)) { 317 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 318 else Set_inexactflag(); 319 } 320 } 321 else { 322 Duint_setzero(resultp1,resultp2); 323 Duint_copytoptr(resultp1,resultp2,dstptr); 324 325 /* check for inexact */ 326 if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) { 327 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION); 328 else Set_inexactflag(); 329 } 330 } 331 return(NOEXCEPTION); 332} 333