1 // SPDX-License-Identifier: GPL-2.0-or-later 1 2 /* 3 * Linux/PA-RISC Project (http://www.parisc-li 4 * 5 * Floating-point emulation code 6 * Copyright (C) 2001 Hewlett-Packard (Paul B 7 */ 8 /* 9 * BEGIN_DESC 10 * 11 * File: 12 * @(#) pa/spmath/fcnvfu.c 13 * 14 * Purpose: 15 * Floating-point to Unsigned Fixed-point 16 * 17 * External Interfaces: 18 * dbl_to_dbl_fcnvfu(srcptr,_nullptr,dstp 19 * dbl_to_sgl_fcnvfu(srcptr,_nullptr,dstp 20 * sgl_to_dbl_fcnvfu(srcptr,_nullptr,dstp 21 * sgl_to_sgl_fcnvfu(srcptr,_nullptr,dstp 22 * 23 * Internal Interfaces: 24 * 25 * Theory: 26 * <<please update with a overview of the 27 * 28 * END_DESC 29 */ 30 31 32 #include "float.h" 33 #include "sgl_float.h" 34 #include "dbl_float.h" 35 #include "cnv_float.h" 36 37 /********************************************* 38 * Floating-point to Unsigned Fixed-point Con 39 ********************************************* 40 41 /* 42 * Single Floating-point to Single Unsigned F 43 */ 44 /*ARGSUSED*/ 45 int 46 sgl_to_sgl_fcnvfu( 47 sgl_floating_point *sr 48 unsigned int *_nullptr 49 unsigned int *dstptr, 50 unsigned int *status) 51 { 52 register unsigned int src, result; 53 register int src_exponent; 54 register boolean inexact = FALSE; 55 56 src = *srcptr; 57 src_exponent = Sgl_exponent(src) - SGL 58 59 /* 60 * Test for overflow 61 */ 62 if (src_exponent > SGL_FX_MAX_EXP + 1) 63 if (Sgl_isone_sign(src)) { 64 result = 0; 65 } else { 66 result = 0xffffffff; 67 } 68 if (Is_invalidtrap_enabled()) 69 return(INVALIDEXCEPTIO 70 } 71 Set_invalidflag(); 72 *dstptr = result; 73 return(NOEXCEPTION); 74 } 75 /* 76 * Generate result 77 */ 78 if (src_exponent >= 0) { 79 /* 80 * Check sign. 81 * If negative, trap unimpleme 82 */ 83 if (Sgl_isone_sign(src)) { 84 result = 0; 85 if (Is_invalidtrap_ena 86 return(INVALID 87 } 88 Set_invalidflag(); 89 *dstptr = result; 90 return(NOEXCEPTION); 91 } 92 Sgl_clear_signexponent_set_hid 93 Suint_from_sgl_mantissa(src,sr 94 95 /* check for inexact */ 96 if (Sgl_isinexact_to_unsigned( 97 inexact = TRUE; 98 /* round result */ 99 switch (Rounding_mode( 100 case ROUNDPLUS: 101 result++; 102 break; 103 case ROUNDMINUS: /* ne 104 break; 105 case ROUNDNEAREST: 106 if (Sgl_isone_ 107 (Sgl_isone 108 (result & 109 result 110 } 111 break; 112 } 113 } 114 } else { 115 result = 0; 116 117 /* check for inexact */ 118 if (Sgl_isnotzero_exponentmant 119 inexact = TRUE; 120 /* round result */ 121 switch (Rounding_mode( 122 case ROUNDPLUS: 123 if (Sgl_iszero 124 result 125 } 126 break; 127 case ROUNDMINUS: 128 if (Sgl_isone_ 129 result 130 if (Is 131 132 } 133 Set_in 134 inexac 135 } 136 break; 137 case ROUNDNEAREST: 138 if (src_expone 139 Sgl_isnotz 140 if (Sg 141 142 143 144 145 146 147 } 148 else r 149 } 150 break; 151 } 152 } 153 } 154 *dstptr = result; 155 if (inexact) { 156 if (Is_inexacttrap_enabled()) 157 else Set_inexactflag(); 158 } 159 return(NOEXCEPTION); 160 } 161 162 /* 163 * Single Floating-point to Double Unsigned F 164 */ 165 /*ARGSUSED*/ 166 int 167 sgl_to_dbl_fcnvfu( 168 sgl_floating_point *srcptr 169 unsigned int *_nullptr, 170 dbl_unsigned *dstptr, 171 unsigned int *status) 172 { 173 register int src_exponent; 174 register unsigned int src, resultp1, r 175 register boolean inexact = FALSE; 176 177 src = *srcptr; 178 src_exponent = Sgl_exponent(src) - SGL 179 180 /* 181 * Test for overflow 182 */ 183 if (src_exponent > DBL_FX_MAX_EXP + 1) 184 if (Sgl_isone_sign(src)) { 185 resultp1 = resultp2 = 186 } else { 187 resultp1 = resultp2 = 188 } 189 if (Is_invalidtrap_enabled()) 190 return(INVALIDEXCEPTIO 191 } 192 Set_invalidflag(); 193 Duint_copytoptr(resultp1,resul 194 return(NOEXCEPTION); 195 } 196 /* 197 * Generate result 198 */ 199 if (src_exponent >= 0) { 200 /* 201 * Check sign. 202 * If negative, trap unimpleme 203 */ 204 if (Sgl_isone_sign(src)) { 205 resultp1 = resultp2 = 206 if (Is_invalidtrap_ena 207 return(INVALID 208 } 209 Set_invalidflag(); 210 Duint_copytoptr(result 211 return(NOEXCEPTION); 212 } 213 Sgl_clear_signexponent_set_hid 214 Duint_from_sgl_mantissa(src,sr 215 216 /* check for inexact */ 217 if (Sgl_isinexact_to_unsigned( 218 inexact = TRUE; 219 /* round result */ 220 switch (Rounding_mode( 221 case ROUNDPLUS: 222 Duint_incremen 223 break; 224 case ROUNDMINUS: /* ne 225 break; 226 case ROUNDNEAREST: 227 if (Sgl_isone_ 228 (Sgl_isone 229 Duint_iso 230 Duint_ 231 } 232 break; 233 } 234 } 235 } else { 236 Duint_setzero(resultp1,resultp 237 238 /* check for inexact */ 239 if (Sgl_isnotzero_exponentmant 240 inexact = TRUE; 241 /* round result */ 242 switch (Rounding_mode( 243 case ROUNDPLUS: 244 if (Sgl_iszero 245 Duint_ 246 } 247 break; 248 case ROUNDMINUS: 249 if (Sgl_isone_ 250 result 251 if (Is 252 253 } 254 Set_in 255 inexac 256 } 257 break; 258 case ROUNDNEAREST: 259 if (src_expone 260 Sgl_isnotz 261 if (Sg 262 263 264 265 266 267 268 269 } 270 else D 271 } 272 } 273 } 274 } 275 Duint_copytoptr(resultp1,resultp2,dstp 276 if (inexact) { 277 if (Is_inexacttrap_enabled()) 278 else Set_inexactflag(); 279 } 280 return(NOEXCEPTION); 281 } 282 283 /* 284 * Double Floating-point to Single Unsigned F 285 */ 286 /*ARGSUSED*/ 287 int 288 dbl_to_sgl_fcnvfu (dbl_floating_point * srcptr 289 unsigned int *dstptr, unsig 290 { 291 register unsigned int srcp1, srcp2, re 292 register int src_exponent; 293 register boolean inexact = FALSE; 294 295 Dbl_copyfromptr(srcptr,srcp1,srcp2); 296 src_exponent = Dbl_exponent(srcp1) - D 297 298 /* 299 * Test for overflow 300 */ 301 if (src_exponent > SGL_FX_MAX_EXP + 1) 302 if (Dbl_isone_sign(srcp1)) { 303 result = 0; 304 } else { 305 result = 0xffffffff; 306 } 307 if (Is_invalidtrap_enabled()) 308 return(INVALIDEXCEPTIO 309 } 310 Set_invalidflag(); 311 *dstptr = result; 312 return(NOEXCEPTION); 313 } 314 /* 315 * Generate result 316 */ 317 if (src_exponent >= 0) { 318 /* 319 * Check sign. 320 * If negative, trap unimpleme 321 */ 322 if (Dbl_isone_sign(srcp1)) { 323 result = 0; 324 if (Is_invalidtrap_ena 325 return(INVALID 326 } 327 Set_invalidflag(); 328 *dstptr = result; 329 return(NOEXCEPTION); 330 } 331 Dbl_clear_signexponent_set_hid 332 Suint_from_dbl_mantissa(srcp1, 333 334 /* check for inexact */ 335 if (Dbl_isinexact_to_unsigned( 336 inexact = TRUE; 337 /* round result */ 338 switch (Rounding_mode( 339 case ROUNDPLUS: 340 result++; 341 break; 342 case ROUNDMINUS: /* ne 343 break; 344 case ROUNDNEAREST: 345 if(Dbl_isone_roun 346 (Dbl_isone_sti 347 result&1)) 348 result++; 349 break; 350 } 351 /* check for overflow 352 if (result == 0) { 353 result = 0xfff 354 if (Is_invalid 355 return 356 } 357 Set_invalidfla 358 *dstptr = resu 359 return(NOEXCEP 360 } 361 } 362 } else { 363 result = 0; 364 365 /* check for inexact */ 366 if (Dbl_isnotzero_exponentmant 367 inexact = TRUE; 368 /* round result */ 369 switch (Rounding_mode( 370 case ROUNDPLUS: 371 if (Dbl_iszero 372 break; 373 case ROUNDMINUS: 374 if (Dbl_isone_ 375 result 376 if (Is 377 378 } 379 Set_in 380 inexac 381 } 382 break; 383 case ROUNDNEAREST: 384 if (src_expone 385 Dbl_isnotz 386 if (Db 387 388 389 390 391 392 393 } 394 else r 395 } 396 } 397 } 398 *dstptr = result; 399 if (inexact) { 400 if (Is_inexacttrap_enabled()) 401 else Set_inexactflag(); 402 } 403 return(NOEXCEPTION); 404 } 405 406 /* 407 * Double Floating-point to Double Unsigned F 408 */ 409 /*ARGSUSED*/ 410 int 411 dbl_to_dbl_fcnvfu (dbl_floating_point * srcptr 412 dbl_unsigned * dstptr, unsi 413 { 414 register int src_exponent; 415 register unsigned int srcp1, srcp2, re 416 register boolean inexact = FALSE; 417 418 Dbl_copyfromptr(srcptr,srcp1,srcp2); 419 src_exponent = Dbl_exponent(srcp1) - D 420 421 /* 422 * Test for overflow 423 */ 424 if (src_exponent > DBL_FX_MAX_EXP + 1) 425 if (Dbl_isone_sign(srcp1)) { 426 resultp1 = resultp2 = 427 } else { 428 resultp1 = resultp2 = 429 } 430 if (Is_invalidtrap_enabled()) 431 return(INVALIDEXCEPTIO 432 } 433 Set_invalidflag(); 434 Duint_copytoptr(resultp1,resul 435 return(NOEXCEPTION); 436 } 437 438 /* 439 * Generate result 440 */ 441 if (src_exponent >= 0) { 442 /* 443 * Check sign. 444 * If negative, trap unimpleme 445 */ 446 if (Dbl_isone_sign(srcp1)) { 447 resultp1 = resultp2 = 448 if (Is_invalidtrap_ena 449 return(INVALID 450 } 451 Set_invalidflag(); 452 Duint_copytoptr(result 453 return(NOEXCEPTION); 454 } 455 Dbl_clear_signexponent_set_hid 456 Duint_from_dbl_mantissa(srcp1, 457 resultp2); 458 459 /* check for inexact */ 460 if (Dbl_isinexact_to_unsigned( 461 inexact = TRUE; 462 /* round result */ 463 switch (Rounding_mode( 464 case ROUNDPLUS: 465 Duint_incremen 466 break; 467 case ROUNDMINUS: /* ne 468 break; 469 case ROUNDNEAREST: 470 if(Dbl_isone_r 471 if(Dbl_isone 472 Duint_iso 473 Duint_ 474 } 475 } 476 } else { 477 Duint_setzero(resultp1,resultp 478 479 /* check for inexact */ 480 if (Dbl_isnotzero_exponentmant 481 inexact = TRUE; 482 /* round result */ 483 switch (Rounding_mode( 484 case ROUNDPLUS: 485 if (Dbl_iszero 486 Duint_ 487 } 488 break; 489 case ROUNDMINUS: 490 if (Dbl_isone_ 491 result 492 if (Is 493 494 } 495 Set_in 496 inexac 497 } 498 break; 499 case ROUNDNEAREST: 500 if (src_expone 501 Dbl_isnotz 502 if (Db 503 504 } else 505 506 507 508 509 510 511 512 } 513 } 514 } 515 } 516 Duint_copytoptr(resultp1,resultp2,dstp 517 if (inexact) { 518 if (Is_inexacttrap_enabled()) 519 else Set_inexactflag(); 520 } 521 return(NOEXCEPTION); 522 } 523 524
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.