1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Linux/PA-RISC Project (http://www.parisc-linux.org/) 4 * 5 * Floating-point emulation code 6 * Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org> 7 */ 8 /* 9 * BEGIN_DESC 10 * 11 * File: 12 * @(#) pa/spmath/fmpyfadd.c $Revision: 1.1 $ 13 * 14 * Purpose: 15 * Double Floating-point Multiply Fused Add 16 * Double Floating-point Multiply Negate Fused Add 17 * Single Floating-point Multiply Fused Add 18 * Single Floating-point Multiply Negate Fused Add 19 * 20 * External Interfaces: 21 * dbl_fmpyfadd(src1ptr,src2ptr,src3ptr,status,dstptr) 22 * dbl_fmpynfadd(src1ptr,src2ptr,src3ptr,status,dstptr) 23 * sgl_fmpyfadd(src1ptr,src2ptr,src3ptr,status,dstptr) 24 * sgl_fmpynfadd(src1ptr,src2ptr,src3ptr,status,dstptr) 25 * 26 * Internal Interfaces: 27 * 28 * Theory: 29 * <<please update with a overview of the operation of this file>> 30 * 31 * END_DESC 32 */ 33 34 35 #include "float.h" 36 #include "sgl_float.h" 37 #include "dbl_float.h" 38 39 40 /* 41 * Double Floating-point Multiply Fused Add 42 */ 43 44 int 45 dbl_fmpyfadd( 46 dbl_floating_point *src1ptr, 47 dbl_floating_point *src2ptr, 48 dbl_floating_point *src3ptr, 49 unsigned int *status, 50 dbl_floating_point *dstptr) 51 { 52 unsigned int opnd1p1, opnd1p2, opnd2p1, opnd2p2, opnd3p1, opnd3p2; 53 register unsigned int tmpresp1, tmpresp2, tmpresp3, tmpresp4; 54 unsigned int rightp1, rightp2, rightp3, rightp4; 55 unsigned int resultp1, resultp2 = 0, resultp3 = 0, resultp4 = 0; 56 register int mpy_exponent, add_exponent, count; 57 boolean inexact = FALSE, is_tiny = FALSE; 58 59 unsigned int signlessleft1, signlessright1, save; 60 register int result_exponent, diff_exponent; 61 int sign_save, jumpsize; 62 63 Dbl_copyfromptr(src1ptr,opnd1p1,opnd1p2); 64 Dbl_copyfromptr(src2ptr,opnd2p1,opnd2p2); 65 Dbl_copyfromptr(src3ptr,opnd3p1,opnd3p2); 66 67 /* 68 * set sign bit of result of multiply 69 */ 70 if (Dbl_sign(opnd1p1) ^ Dbl_sign(opnd2p1)) 71 Dbl_setnegativezerop1(resultp1); 72 else Dbl_setzerop1(resultp1); 73 74 /* 75 * Generate multiply exponent 76 */ 77 mpy_exponent = Dbl_exponent(opnd1p1) + Dbl_exponent(opnd2p1) - DBL_BIAS; 78 79 /* 80 * check first operand for NaN's or infinity 81 */ 82 if (Dbl_isinfinity_exponent(opnd1p1)) { 83 if (Dbl_iszero_mantissa(opnd1p1,opnd1p2)) { 84 if (Dbl_isnotnan(opnd2p1,opnd2p2) && 85 Dbl_isnotnan(opnd3p1,opnd3p2)) { 86 if (Dbl_iszero_exponentmantissa(opnd2p1,opnd2p2)) { 87 /* 88 * invalid since operands are infinity 89 * and zero 90 */ 91 if (Is_invalidtrap_enabled()) 92 return(OPC_2E_INVALIDEXCEPTION); 93 Set_invalidflag(); 94 Dbl_makequietnan(resultp1,resultp2); 95 Dbl_copytoptr(resultp1,resultp2,dstptr); 96 return(NOEXCEPTION); 97 } 98 /* 99 * Check third operand for infinity with a 100 * sign opposite of the multiply result 101 */ 102 if (Dbl_isinfinity(opnd3p1,opnd3p2) && 103 (Dbl_sign(resultp1) ^ Dbl_sign(opnd3p1))) { 104 /* 105 * invalid since attempting a magnitude 106 * subtraction of infinities 107 */ 108 if (Is_invalidtrap_enabled()) 109 return(OPC_2E_INVALIDEXCEPTION); 110 Set_invalidflag(); 111 Dbl_makequietnan(resultp1,resultp2); 112 Dbl_copytoptr(resultp1,resultp2,dstptr); 113 return(NOEXCEPTION); 114 } 115 116 /* 117 * return infinity 118 */ 119 Dbl_setinfinity_exponentmantissa(resultp1,resultp2); 120 Dbl_copytoptr(resultp1,resultp2,dstptr); 121 return(NOEXCEPTION); 122 } 123 } 124 else { 125 /* 126 * is NaN; signaling or quiet? 127 */ 128 if (Dbl_isone_signaling(opnd1p1)) { 129 /* trap if INVALIDTRAP enabled */ 130 if (Is_invalidtrap_enabled()) 131 return(OPC_2E_INVALIDEXCEPTION); 132 /* make NaN quiet */ 133 Set_invalidflag(); 134 Dbl_set_quiet(opnd1p1); 135 } 136 /* 137 * is second operand a signaling NaN? 138 */ 139 else if (Dbl_is_signalingnan(opnd2p1)) { 140 /* trap if INVALIDTRAP enabled */ 141 if (Is_invalidtrap_enabled()) 142 return(OPC_2E_INVALIDEXCEPTION); 143 /* make NaN quiet */ 144 Set_invalidflag(); 145 Dbl_set_quiet(opnd2p1); 146 Dbl_copytoptr(opnd2p1,opnd2p2,dstptr); 147 return(NOEXCEPTION); 148 } 149 /* 150 * is third operand a signaling NaN? 151 */ 152 else if (Dbl_is_signalingnan(opnd3p1)) { 153 /* trap if INVALIDTRAP enabled */ 154 if (Is_invalidtrap_enabled()) 155 return(OPC_2E_INVALIDEXCEPTION); 156 /* make NaN quiet */ 157 Set_invalidflag(); 158 Dbl_set_quiet(opnd3p1); 159 Dbl_copytoptr(opnd3p1,opnd3p2,dstptr); 160 return(NOEXCEPTION); 161 } 162 /* 163 * return quiet NaN 164 */ 165 Dbl_copytoptr(opnd1p1,opnd1p2,dstptr); 166 return(NOEXCEPTION); 167 } 168 } 169 170 /* 171 * check second operand for NaN's or infinity 172 */ 173 if (Dbl_isinfinity_exponent(opnd2p1)) { 174 if (Dbl_iszero_mantissa(opnd2p1,opnd2p2)) { 175 if (Dbl_isnotnan(opnd3p1,opnd3p2)) { 176 if (Dbl_iszero_exponentmantissa(opnd1p1,opnd1p2)) { 177 /* 178 * invalid since multiply operands are 179 * zero & infinity 180 */ 181 if (Is_invalidtrap_enabled()) 182 return(OPC_2E_INVALIDEXCEPTION); 183 Set_invalidflag(); 184 Dbl_makequietnan(opnd2p1,opnd2p2); 185 Dbl_copytoptr(opnd2p1,opnd2p2,dstptr); 186 return(NOEXCEPTION); 187 } 188 189 /* 190 * Check third operand for infinity with a 191 * sign opposite of the multiply result 192 */ 193 if (Dbl_isinfinity(opnd3p1,opnd3p2) && 194 (Dbl_sign(resultp1) ^ Dbl_sign(opnd3p1))) { 195 /* 196 * invalid since attempting a magnitude 197 * subtraction of infinities 198 */ 199 if (Is_invalidtrap_enabled()) 200 return(OPC_2E_INVALIDEXCEPTION); 201 Set_invalidflag(); 202 Dbl_makequietnan(resultp1,resultp2); 203 Dbl_copytoptr(resultp1,resultp2,dstptr); 204 return(NOEXCEPTION); 205 } 206 207 /* 208 * return infinity 209 */ 210 Dbl_setinfinity_exponentmantissa(resultp1,resultp2); 211 Dbl_copytoptr(resultp1,resultp2,dstptr); 212 return(NOEXCEPTION); 213 } 214 } 215 else { 216 /* 217 * is NaN; signaling or quiet? 218 */ 219 if (Dbl_isone_signaling(opnd2p1)) { 220 /* trap if INVALIDTRAP enabled */ 221 if (Is_invalidtrap_enabled()) 222 return(OPC_2E_INVALIDEXCEPTION); 223 /* make NaN quiet */ 224 Set_invalidflag(); 225 Dbl_set_quiet(opnd2p1); 226 } 227 /* 228 * is third operand a signaling NaN? 229 */ 230 else if (Dbl_is_signalingnan(opnd3p1)) { 231 /* trap if INVALIDTRAP enabled */ 232 if (Is_invalidtrap_enabled()) 233 return(OPC_2E_INVALIDEXCEPTION); 234 /* make NaN quiet */ 235 Set_invalidflag(); 236 Dbl_set_quiet(opnd3p1); 237 Dbl_copytoptr(opnd3p1,opnd3p2,dstptr); 238 return(NOEXCEPTION); 239 } 240 /* 241 * return quiet NaN 242 */ 243 Dbl_copytoptr(opnd2p1,opnd2p2,dstptr); 244 return(NOEXCEPTION); 245 } 246 } 247 248 /* 249 * check third operand for NaN's or infinity 250 */ 251 if (Dbl_isinfinity_exponent(opnd3p1)) { 252 if (Dbl_iszero_mantissa(opnd3p1,opnd3p2)) { 253 /* return infinity */ 254 Dbl_copytoptr(opnd3p1,opnd3p2,dstptr); 255 return(NOEXCEPTION); 256 } else { 257 /* 258 * is NaN; signaling or quiet? 259 */ 260 if (Dbl_isone_signaling(opnd3p1)) { 261 /* trap if INVALIDTRAP enabled */ 262 if (Is_invalidtrap_enabled()) 263 return(OPC_2E_INVALIDEXCEPTION); 264 /* make NaN quiet */ 265 Set_invalidflag(); 266 Dbl_set_quiet(opnd3p1); 267 } 268 /* 269 * return quiet NaN 270 */ 271 Dbl_copytoptr(opnd3p1,opnd3p2,dstptr); 272 return(NOEXCEPTION); 273 } 274 } 275 276 /* 277 * Generate multiply mantissa 278 */ 279 if (Dbl_isnotzero_exponent(opnd1p1)) { 280 /* set hidden bit */ 281 Dbl_clear_signexponent_set_hidden(opnd1p1); 282 } 283 else { 284 /* check for zero */ 285 if (Dbl_iszero_mantissa(opnd1p1,opnd1p2)) { 286 /* 287 * Perform the add opnd3 with zero here. 288 */ 289 if (Dbl_iszero_exponentmantissa(opnd3p1,opnd3p2)) { 290 if (Is_rounding_mode(ROUNDMINUS)) { 291 Dbl_or_signs(opnd3p1,resultp1); 292 } else { 293 Dbl_and_signs(opnd3p1,resultp1); 294 } 295 } 296 /* 297 * Now let's check for trapped underflow case. 298 */ 299 else if (Dbl_iszero_exponent(opnd3p1) && 300 Is_underflowtrap_enabled()) { 301 /* need to normalize results mantissa */ 302 sign_save = Dbl_signextendedsign(opnd3p1); 303 result_exponent = 0; 304 Dbl_leftshiftby1(opnd3p1,opnd3p2); 305 Dbl_normalize(opnd3p1,opnd3p2,result_exponent); 306 Dbl_set_sign(opnd3p1,/*using*/sign_save); 307 Dbl_setwrapped_exponent(opnd3p1,result_exponent, 308 unfl); 309 Dbl_copytoptr(opnd3p1,opnd3p2,dstptr); 310 /* inexact = FALSE */ 311 return(OPC_2E_UNDERFLOWEXCEPTION); 312 } 313 Dbl_copytoptr(opnd3p1,opnd3p2,dstptr); 314 return(NOEXCEPTION); 315 } 316 /* is denormalized, adjust exponent */ 317 Dbl_clear_signexponent(opnd1p1); 318 Dbl_leftshiftby1(opnd1p1,opnd1p2); 319 Dbl_normalize(opnd1p1,opnd1p2,mpy_exponent); 320 } 321 /* opnd2 needs to have hidden bit set with msb in hidden bit */ 322 if (Dbl_isnotzero_exponent(opnd2p1)) { 323 Dbl_clear_signexponent_set_hidden(opnd2p1); 324 } 325 else { 326 /* check for zero */ 327 if (Dbl_iszero_mantissa(opnd2p1,opnd2p2)) { 328 /* 329 * Perform the add opnd3 with zero here. 330 */ 331 if (Dbl_iszero_exponentmantissa(opnd3p1,opnd3p2)) { 332 if (Is_rounding_mode(ROUNDMINUS)) { 333 Dbl_or_signs(opnd3p1,resultp1); 334 } else { 335 Dbl_and_signs(opnd3p1,resultp1); 336 } 337 } 338 /* 339 * Now let's check for trapped underflow case. 340 */ 341 else if (Dbl_iszero_exponent(opnd3p1) && 342 Is_underflowtrap_enabled()) { 343 /* need to normalize results mantissa */ 344 sign_save = Dbl_signextendedsign(opnd3p1); 345 result_exponent = 0; 346 Dbl_leftshiftby1(opnd3p1,opnd3p2); 347 Dbl_normalize(opnd3p1,opnd3p2,result_exponent); 348 Dbl_set_sign(opnd3p1,/*using*/sign_save); 349 Dbl_setwrapped_exponent(opnd3p1,result_exponent, 350 unfl); 351 Dbl_copytoptr(opnd3p1,opnd3p2,dstptr); 352 /* inexact = FALSE */ 353 return(OPC_2E_UNDERFLOWEXCEPTION); 354 } 355 Dbl_copytoptr(opnd3p1,opnd3p2,dstptr); 356 return(NOEXCEPTION); 357 } 358 /* is denormalized; want to normalize */ 359 Dbl_clear_signexponent(opnd2p1); 360 Dbl_leftshiftby1(opnd2p1,opnd2p2); 361 Dbl_normalize(opnd2p1,opnd2p2,mpy_exponent); 362 } 363 364 /* Multiply the first two source mantissas together */ 365 366 /* 367 * The intermediate result will be kept in tmpres, 368 * which needs enough room for 106 bits of mantissa, 369 * so lets call it a Double extended. 370 */ 371 Dblext_setzero(tmpresp1,tmpresp2,tmpresp3,tmpresp4); 372 373 /* 374 * Four bits at a time are inspected in each loop, and a 375 * simple shift and add multiply algorithm is used. 376 */ 377 for (count = DBL_P-1; count >= 0; count -= 4) { 378 Dblext_rightshiftby4(tmpresp1,tmpresp2,tmpresp3,tmpresp4); 379 if (Dbit28p2(opnd1p2)) { 380 /* Fourword_add should be an ADD followed by 3 ADDC's */ 381 Fourword_add(tmpresp1, tmpresp2, tmpresp3, tmpresp4, 382 opnd2p1<<3 | opnd2p2>>29, opnd2p2<<3, 0, 0); 383 } 384 if (Dbit29p2(opnd1p2)) { 385 Fourword_add(tmpresp1, tmpresp2, tmpresp3, tmpresp4, 386 opnd2p1<<2 | opnd2p2>>30, opnd2p2<<2, 0, 0); 387 } 388 if (Dbit30p2(opnd1p2)) { 389 Fourword_add(tmpresp1, tmpresp2, tmpresp3, tmpresp4, 390 opnd2p1<<1 | opnd2p2>>31, opnd2p2<<1, 0, 0); 391 } 392 if (Dbit31p2(opnd1p2)) { 393 Fourword_add(tmpresp1, tmpresp2, tmpresp3, tmpresp4, 394 opnd2p1, opnd2p2, 0, 0); 395 } 396 Dbl_rightshiftby4(opnd1p1,opnd1p2); 397 } 398 if (Is_dexthiddenoverflow(tmpresp1)) { 399 /* result mantissa >= 2 (mantissa overflow) */ 400 mpy_exponent++; 401 Dblext_rightshiftby1(tmpresp1,tmpresp2,tmpresp3,tmpresp4); 402 } 403 404 /* 405 * Restore the sign of the mpy result which was saved in resultp1. 406 * The exponent will continue to be kept in mpy_exponent. 407 */ 408 Dblext_set_sign(tmpresp1,Dbl_sign(resultp1)); 409 410 /* 411 * No rounding is required, since the result of the multiply 412 * is exact in the extended format. 413 */ 414 415 /* 416 * Now we are ready to perform the add portion of the operation. 417 * 418 * The exponents need to be kept as integers for now, since the 419 * multiply result might not fit into the exponent field. We 420 * can't overflow or underflow because of this yet, since the 421 * add could bring the final result back into range. 422 */ 423 add_exponent = Dbl_exponent(opnd3p1); 424 425 /* 426 * Check for denormalized or zero add operand. 427 */ 428 if (add_exponent == 0) { 429 /* check for zero */ 430 if (Dbl_iszero_mantissa(opnd3p1,opnd3p2)) { 431 /* right is zero */ 432 /* Left can't be zero and must be result. 433 * 434 * The final result is now in tmpres and mpy_exponent, 435 * and needs to be rounded and squeezed back into 436 * double precision format from double extended. 437 */ 438 result_exponent = mpy_exponent; 439 Dblext_copy(tmpresp1,tmpresp2,tmpresp3,tmpresp4, 440 resultp1,resultp2,resultp3,resultp4); 441 sign_save = Dbl_signextendedsign(resultp1);/*save sign*/ 442 goto round; 443 } 444 445 /* 446 * Neither are zeroes. 447 * Adjust exponent and normalize add operand. 448 */ 449 sign_save = Dbl_signextendedsign(opnd3p1); /* save sign */ 450 Dbl_clear_signexponent(opnd3p1); 451 Dbl_leftshiftby1(opnd3p1,opnd3p2); 452 Dbl_normalize(opnd3p1,opnd3p2,add_exponent); 453 Dbl_set_sign(opnd3p1,sign_save); /* restore sign */ 454 } else { 455 Dbl_clear_exponent_set_hidden(opnd3p1); 456 } 457 /* 458 * Copy opnd3 to the double extended variable called right. 459 */ 460 Dbl_copyto_dblext(opnd3p1,opnd3p2,rightp1,rightp2,rightp3,rightp4); 461 462 /* 463 * A zero "save" helps discover equal operands (for later), 464 * and is used in swapping operands (if needed). 465 */ 466 Dblext_xortointp1(tmpresp1,rightp1,/*to*/save); 467 468 /* 469 * Compare magnitude of operands. 470 */ 471 Dblext_copytoint_exponentmantissap1(tmpresp1,signlessleft1); 472 Dblext_copytoint_exponentmantissap1(rightp1,signlessright1); 473 if (mpy_exponent < add_exponent || mpy_exponent == add_exponent && 474 Dblext_ismagnitudeless(tmpresp2,rightp2,signlessleft1,signlessright1)){ 475 /* 476 * Set the left operand to the larger one by XOR swap. 477 * First finish the first word "save". 478 */ 479 Dblext_xorfromintp1(save,rightp1,/*to*/rightp1); 480 Dblext_xorfromintp1(save,tmpresp1,/*to*/tmpresp1); 481 Dblext_swap_lower(tmpresp2,tmpresp3,tmpresp4, 482 rightp2,rightp3,rightp4); 483 /* also setup exponents used in rest of routine */ 484 diff_exponent = add_exponent - mpy_exponent; 485 result_exponent = add_exponent; 486 } else { 487 /* also setup exponents used in rest of routine */ 488 diff_exponent = mpy_exponent - add_exponent; 489 result_exponent = mpy_exponent; 490 } 491 /* Invariant: left is not smaller than right. */ 492 493 /* 494 * Special case alignment of operands that would force alignment 495 * beyond the extent of the extension. A further optimization 496 * could special case this but only reduces the path length for 497 * this infrequent case. 498 */ 499 if (diff_exponent > DBLEXT_THRESHOLD) { 500 diff_exponent = DBLEXT_THRESHOLD; 501 } 502 503 /* Align right operand by shifting it to the right */ 504 Dblext_clear_sign(rightp1); 505 Dblext_right_align(rightp1,rightp2,rightp3,rightp4, 506 /*shifted by*/diff_exponent); 507 508 /* Treat sum and difference of the operands separately. */ 509 if ((int)save < 0) { 510 /* 511 * Difference of the two operands. Overflow can occur if the 512 * multiply overflowed. A borrow can occur out of the hidden 513 * bit and force a post normalization phase. 514 */ 515 Dblext_subtract(tmpresp1,tmpresp2,tmpresp3,tmpresp4, 516 rightp1,rightp2,rightp3,rightp4, 517 resultp1,resultp2,resultp3,resultp4); 518 sign_save = Dbl_signextendedsign(resultp1); 519 if (Dbl_iszero_hidden(resultp1)) { 520 /* Handle normalization */ 521 /* A straightforward algorithm would now shift the 522 * result and extension left until the hidden bit 523 * becomes one. Not all of the extension bits need 524 * participate in the shift. Only the two most 525 * significant bits (round and guard) are needed. 526 * If only a single shift is needed then the guard 527 * bit becomes a significant low order bit and the 528 * extension must participate in the rounding. 529 * If more than a single shift is needed, then all 530 * bits to the right of the guard bit are zeros, 531 * and the guard bit may or may not be zero. */ 532 Dblext_leftshiftby1(resultp1,resultp2,resultp3, 533 resultp4); 534 535 /* Need to check for a zero result. The sign and 536 * exponent fields have already been zeroed. The more 537 * efficient test of the full object can be used. 538 */ 539 if(Dblext_iszero(resultp1,resultp2,resultp3,resultp4)){ 540 /* Must have been "x-x" or "x+(-x)". */ 541 if (Is_rounding_mode(ROUNDMINUS)) 542 Dbl_setone_sign(resultp1); 543 Dbl_copytoptr(resultp1,resultp2,dstptr); 544 return(NOEXCEPTION); 545 } 546 result_exponent--; 547 548 /* Look to see if normalization is finished. */ 549 if (Dbl_isone_hidden(resultp1)) { 550 /* No further normalization is needed */ 551 goto round; 552 } 553 554 /* Discover first one bit to determine shift amount. 555 * Use a modified binary search. We have already 556 * shifted the result one position right and still 557 * not found a one so the remainder of the extension 558 * must be zero and simplifies rounding. */ 559 /* Scan bytes */ 560 while (Dbl_iszero_hiddenhigh7mantissa(resultp1)) { 561 Dblext_leftshiftby8(resultp1,resultp2,resultp3,resultp4); 562 result_exponent -= 8; 563 } 564 /* Now narrow it down to the nibble */ 565 if (Dbl_iszero_hiddenhigh3mantissa(resultp1)) { 566 /* The lower nibble contains the 567 * normalizing one */ 568 Dblext_leftshiftby4(resultp1,resultp2,resultp3,resultp4); 569 result_exponent -= 4; 570 } 571 /* Select case where first bit is set (already 572 * normalized) otherwise select the proper shift. */ 573 jumpsize = Dbl_hiddenhigh3mantissa(resultp1); 574 if (jumpsize <= 7) switch(jumpsize) { 575 case 1: 576 Dblext_leftshiftby3(resultp1,resultp2,resultp3, 577 resultp4); 578 result_exponent -= 3; 579 break; 580 case 2: 581 case 3: 582 Dblext_leftshiftby2(resultp1,resultp2,resultp3, 583 resultp4); 584 result_exponent -= 2; 585 break; 586 case 4: 587 case 5: 588 case 6: 589 case 7: 590 Dblext_leftshiftby1(resultp1,resultp2,resultp3, 591 resultp4); 592 result_exponent -= 1; 593 break; 594 } 595 } /* end if (hidden...)... */ 596 /* Fall through and round */ 597 } /* end if (save < 0)... */ 598 else { 599 /* Add magnitudes */ 600 Dblext_addition(tmpresp1,tmpresp2,tmpresp3,tmpresp4, 601 rightp1,rightp2,rightp3,rightp4, 602 /*to*/resultp1,resultp2,resultp3,resultp4); 603 sign_save = Dbl_signextendedsign(resultp1); 604 if (Dbl_isone_hiddenoverflow(resultp1)) { 605 /* Prenormalization required. */ 606 Dblext_arithrightshiftby1(resultp1,resultp2,resultp3, 607 resultp4); 608 result_exponent++; 609 } /* end if hiddenoverflow... */ 610 } /* end else ...add magnitudes... */ 611 612 /* Round the result. If the extension and lower two words are 613 * all zeros, then the result is exact. Otherwise round in the 614 * correct direction. Underflow is possible. If a postnormalization 615 * is necessary, then the mantissa is all zeros so no shift is needed. 616 */ 617 round: 618 if (result_exponent <= 0 && !Is_underflowtrap_enabled()) { 619 Dblext_denormalize(resultp1,resultp2,resultp3,resultp4, 620 result_exponent,is_tiny); 621 } 622 Dbl_set_sign(resultp1,/*using*/sign_save); 623 if (Dblext_isnotzero_mantissap3(resultp3) || 624 Dblext_isnotzero_mantissap4(resultp4)) { 625 inexact = TRUE; 626 switch(Rounding_mode()) { 627 case ROUNDNEAREST: /* The default. */ 628 if (Dblext_isone_highp3(resultp3)) { 629 /* at least 1/2 ulp */ 630 if (Dblext_isnotzero_low31p3(resultp3) || 631 Dblext_isnotzero_mantissap4(resultp4) || 632 Dblext_isone_lowp2(resultp2)) { 633 /* either exactly half way and odd or 634 * more than 1/2ulp */ 635 Dbl_increment(resultp1,resultp2); 636 } 637 } 638 break; 639 640 case ROUNDPLUS: 641 if (Dbl_iszero_sign(resultp1)) { 642 /* Round up positive results */ 643 Dbl_increment(resultp1,resultp2); 644 } 645 break; 646 647 case ROUNDMINUS: 648 if (Dbl_isone_sign(resultp1)) { 649 /* Round down negative results */ 650 Dbl_increment(resultp1,resultp2); 651 } 652 653 case ROUNDZERO:; 654 /* truncate is simple */ 655 } /* end switch... */ 656 if (Dbl_isone_hiddenoverflow(resultp1)) result_exponent++; 657 } 658 if (result_exponent >= DBL_INFINITY_EXPONENT) { 659 /* trap if OVERFLOWTRAP enabled */ 660 if (Is_overflowtrap_enabled()) { 661 /* 662 * Adjust bias of result 663 */ 664 Dbl_setwrapped_exponent(resultp1,result_exponent,ovfl); 665 Dbl_copytoptr(resultp1,resultp2,dstptr); 666 if (inexact) 667 if (Is_inexacttrap_enabled()) 668 return (OPC_2E_OVERFLOWEXCEPTION | 669 OPC_2E_INEXACTEXCEPTION); 670 else Set_inexactflag(); 671 return (OPC_2E_OVERFLOWEXCEPTION); 672 } 673 inexact = TRUE; 674 Set_overflowflag(); 675 /* set result to infinity or largest number */ 676 Dbl_setoverflow(resultp1,resultp2); 677 678 } else if (result_exponent <= 0) { /* underflow case */ 679 if (Is_underflowtrap_enabled()) { 680 /* 681 * Adjust bias of result 682 */ 683 Dbl_setwrapped_exponent(resultp1,result_exponent,unfl); 684 Dbl_copytoptr(resultp1,resultp2,dstptr); 685 if (inexact) 686 if (Is_inexacttrap_enabled()) 687 return (OPC_2E_UNDERFLOWEXCEPTION | 688 OPC_2E_INEXACTEXCEPTION); 689 else Set_inexactflag(); 690 return(OPC_2E_UNDERFLOWEXCEPTION); 691 } 692 else if (inexact && is_tiny) Set_underflowflag(); 693 } 694 else Dbl_set_exponent(resultp1,result_exponent); 695 Dbl_copytoptr(resultp1,resultp2,dstptr); 696 if (inexact) 697 if (Is_inexacttrap_enabled()) return(OPC_2E_INEXACTEXCEPTION); 698 else Set_inexactflag(); 699 return(NOEXCEPTION); 700 } 701 702 /* 703 * Double Floating-point Multiply Negate Fused Add 704 */ 705 706 dbl_fmpynfadd(src1ptr,src2ptr,src3ptr,status,dstptr) 707 708 dbl_floating_point *src1ptr, *src2ptr, *src3ptr, *dstptr; 709 unsigned int *status; 710 { 711 unsigned int opnd1p1, opnd1p2, opnd2p1, opnd2p2, opnd3p1, opnd3p2; 712 register unsigned int tmpresp1, tmpresp2, tmpresp3, tmpresp4; 713 unsigned int rightp1, rightp2, rightp3, rightp4; 714 unsigned int resultp1, resultp2 = 0, resultp3 = 0, resultp4 = 0; 715 register int mpy_exponent, add_exponent, count; 716 boolean inexact = FALSE, is_tiny = FALSE; 717 718 unsigned int signlessleft1, signlessright1, save; 719 register int result_exponent, diff_exponent; 720 int sign_save, jumpsize; 721 722 Dbl_copyfromptr(src1ptr,opnd1p1,opnd1p2); 723 Dbl_copyfromptr(src2ptr,opnd2p1,opnd2p2); 724 Dbl_copyfromptr(src3ptr,opnd3p1,opnd3p2); 725 726 /* 727 * set sign bit of result of multiply 728 */ 729 if (Dbl_sign(opnd1p1) ^ Dbl_sign(opnd2p1)) 730 Dbl_setzerop1(resultp1); 731 else 732 Dbl_setnegativezerop1(resultp1); 733 734 /* 735 * Generate multiply exponent 736 */ 737 mpy_exponent = Dbl_exponent(opnd1p1) + Dbl_exponent(opnd2p1) - DBL_BIAS; 738 739 /* 740 * check first operand for NaN's or infinity 741 */ 742 if (Dbl_isinfinity_exponent(opnd1p1)) { 743 if (Dbl_iszero_mantissa(opnd1p1,opnd1p2)) { 744 if (Dbl_isnotnan(opnd2p1,opnd2p2) && 745 Dbl_isnotnan(opnd3p1,opnd3p2)) { 746 if (Dbl_iszero_exponentmantissa(opnd2p1,opnd2p2)) { 747 /* 748 * invalid since operands are infinity 749 * and zero 750 */ 751 if (Is_invalidtrap_enabled()) 752 return(OPC_2E_INVALIDEXCEPTION); 753 Set_invalidflag(); 754 Dbl_makequietnan(resultp1,resultp2); 755 Dbl_copytoptr(resultp1,resultp2,dstptr); 756 return(NOEXCEPTION); 757 } 758 /* 759 * Check third operand for infinity with a 760 * sign opposite of the multiply result 761 */ 762 if (Dbl_isinfinity(opnd3p1,opnd3p2) && 763 (Dbl_sign(resultp1) ^ Dbl_sign(opnd3p1))) { 764 /* 765 * invalid since attempting a magnitude 766 * subtraction of infinities 767 */ 768 if (Is_invalidtrap_enabled()) 769 return(OPC_2E_INVALIDEXCEPTION); 770 Set_invalidflag(); 771 Dbl_makequietnan(resultp1,resultp2); 772 Dbl_copytoptr(resultp1,resultp2,dstptr); 773 return(NOEXCEPTION); 774 } 775 776 /* 777 * return infinity 778 */ 779 Dbl_setinfinity_exponentmantissa(resultp1,resultp2); 780 Dbl_copytoptr(resultp1,resultp2,dstptr); 781 return(NOEXCEPTION); 782 } 783 } 784 else { 785 /* 786 * is NaN; signaling or quiet? 787 */ 788 if (Dbl_isone_signaling(opnd1p1)) { 789 /* trap if INVALIDTRAP enabled */ 790 if (Is_invalidtrap_enabled()) 791 return(OPC_2E_INVALIDEXCEPTION); 792 /* make NaN quiet */ 793 Set_invalidflag(); 794 Dbl_set_quiet(opnd1p1); 795 } 796 /* 797 * is second operand a signaling NaN? 798 */ 799 else if (Dbl_is_signalingnan(opnd2p1)) { 800 /* trap if INVALIDTRAP enabled */ 801 if (Is_invalidtrap_enabled()) 802 return(OPC_2E_INVALIDEXCEPTION); 803 /* make NaN quiet */ 804 Set_invalidflag(); 805 Dbl_set_quiet(opnd2p1); 806 Dbl_copytoptr(opnd2p1,opnd2p2,dstptr); 807 return(NOEXCEPTION); 808 } 809 /* 810 * is third operand a signaling NaN? 811 */ 812 else if (Dbl_is_signalingnan(opnd3p1)) { 813 /* trap if INVALIDTRAP enabled */ 814 if (Is_invalidtrap_enabled()) 815 return(OPC_2E_INVALIDEXCEPTION); 816 /* make NaN quiet */ 817 Set_invalidflag(); 818 Dbl_set_quiet(opnd3p1); 819 Dbl_copytoptr(opnd3p1,opnd3p2,dstptr); 820 return(NOEXCEPTION); 821 } 822 /* 823 * return quiet NaN 824 */ 825 Dbl_copytoptr(opnd1p1,opnd1p2,dstptr); 826 return(NOEXCEPTION); 827 } 828 } 829 830 /* 831 * check second operand for NaN's or infinity 832 */ 833 if (Dbl_isinfinity_exponent(opnd2p1)) { 834 if (Dbl_iszero_mantissa(opnd2p1,opnd2p2)) { 835 if (Dbl_isnotnan(opnd3p1,opnd3p2)) { 836 if (Dbl_iszero_exponentmantissa(opnd1p1,opnd1p2)) { 837 /* 838 * invalid since multiply operands are 839 * zero & infinity 840 */ 841 if (Is_invalidtrap_enabled()) 842 return(OPC_2E_INVALIDEXCEPTION); 843 Set_invalidflag(); 844 Dbl_makequietnan(opnd2p1,opnd2p2); 845 Dbl_copytoptr(opnd2p1,opnd2p2,dstptr); 846 return(NOEXCEPTION); 847 } 848 849 /* 850 * Check third operand for infinity with a 851 * sign opposite of the multiply result 852 */ 853 if (Dbl_isinfinity(opnd3p1,opnd3p2) && 854 (Dbl_sign(resultp1) ^ Dbl_sign(opnd3p1))) { 855 /* 856 * invalid since attempting a magnitude 857 * subtraction of infinities 858 */ 859 if (Is_invalidtrap_enabled()) 860 return(OPC_2E_INVALIDEXCEPTION); 861 Set_invalidflag(); 862 Dbl_makequietnan(resultp1,resultp2); 863 Dbl_copytoptr(resultp1,resultp2,dstptr); 864 return(NOEXCEPTION); 865 } 866 867 /* 868 * return infinity 869 */ 870 Dbl_setinfinity_exponentmantissa(resultp1,resultp2); 871 Dbl_copytoptr(resultp1,resultp2,dstptr); 872 return(NOEXCEPTION); 873 } 874 } 875 else { 876 /* 877 * is NaN; signaling or quiet? 878 */ 879 if (Dbl_isone_signaling(opnd2p1)) { 880 /* trap if INVALIDTRAP enabled */ 881 if (Is_invalidtrap_enabled()) 882 return(OPC_2E_INVALIDEXCEPTION); 883 /* make NaN quiet */ 884 Set_invalidflag(); 885 Dbl_set_quiet(opnd2p1); 886 } 887 /* 888 * is third operand a signaling NaN? 889 */ 890 else if (Dbl_is_signalingnan(opnd3p1)) { 891 /* trap if INVALIDTRAP enabled */ 892 if (Is_invalidtrap_enabled()) 893 return(OPC_2E_INVALIDEXCEPTION); 894 /* make NaN quiet */ 895 Set_invalidflag(); 896 Dbl_set_quiet(opnd3p1); 897 Dbl_copytoptr(opnd3p1,opnd3p2,dstptr); 898 return(NOEXCEPTION); 899 } 900 /* 901 * return quiet NaN 902 */ 903 Dbl_copytoptr(opnd2p1,opnd2p2,dstptr); 904 return(NOEXCEPTION); 905 } 906 } 907 908 /* 909 * check third operand for NaN's or infinity 910 */ 911 if (Dbl_isinfinity_exponent(opnd3p1)) { 912 if (Dbl_iszero_mantissa(opnd3p1,opnd3p2)) { 913 /* return infinity */ 914 Dbl_copytoptr(opnd3p1,opnd3p2,dstptr); 915 return(NOEXCEPTION); 916 } else { 917 /* 918 * is NaN; signaling or quiet? 919 */ 920 if (Dbl_isone_signaling(opnd3p1)) { 921 /* trap if INVALIDTRAP enabled */ 922 if (Is_invalidtrap_enabled()) 923 return(OPC_2E_INVALIDEXCEPTION); 924 /* make NaN quiet */ 925 Set_invalidflag(); 926 Dbl_set_quiet(opnd3p1); 927 } 928 /* 929 * return quiet NaN 930 */ 931 Dbl_copytoptr(opnd3p1,opnd3p2,dstptr); 932 return(NOEXCEPTION); 933 } 934 } 935 936 /* 937 * Generate multiply mantissa 938 */ 939 if (Dbl_isnotzero_exponent(opnd1p1)) { 940 /* set hidden bit */ 941 Dbl_clear_signexponent_set_hidden(opnd1p1); 942 } 943 else { 944 /* check for zero */ 945 if (Dbl_iszero_mantissa(opnd1p1,opnd1p2)) { 946 /* 947 * Perform the add opnd3 with zero here. 948 */ 949 if (Dbl_iszero_exponentmantissa(opnd3p1,opnd3p2)) { 950 if (Is_rounding_mode(ROUNDMINUS)) { 951 Dbl_or_signs(opnd3p1,resultp1); 952 } else { 953 Dbl_and_signs(opnd3p1,resultp1); 954 } 955 } 956 /* 957 * Now let's check for trapped underflow case. 958 */ 959 else if (Dbl_iszero_exponent(opnd3p1) && 960 Is_underflowtrap_enabled()) { 961 /* need to normalize results mantissa */ 962 sign_save = Dbl_signextendedsign(opnd3p1); 963 result_exponent = 0; 964 Dbl_leftshiftby1(opnd3p1,opnd3p2); 965 Dbl_normalize(opnd3p1,opnd3p2,result_exponent); 966 Dbl_set_sign(opnd3p1,/*using*/sign_save); 967 Dbl_setwrapped_exponent(opnd3p1,result_exponent, 968 unfl); 969 Dbl_copytoptr(opnd3p1,opnd3p2,dstptr); 970 /* inexact = FALSE */ 971 return(OPC_2E_UNDERFLOWEXCEPTION); 972 } 973 Dbl_copytoptr(opnd3p1,opnd3p2,dstptr); 974 return(NOEXCEPTION); 975 } 976 /* is denormalized, adjust exponent */ 977 Dbl_clear_signexponent(opnd1p1); 978 Dbl_leftshiftby1(opnd1p1,opnd1p2); 979 Dbl_normalize(opnd1p1,opnd1p2,mpy_exponent); 980 } 981 /* opnd2 needs to have hidden bit set with msb in hidden bit */ 982 if (Dbl_isnotzero_exponent(opnd2p1)) { 983 Dbl_clear_signexponent_set_hidden(opnd2p1); 984 } 985 else { 986 /* check for zero */ 987 if (Dbl_iszero_mantissa(opnd2p1,opnd2p2)) { 988 /* 989 * Perform the add opnd3 with zero here. 990 */ 991 if (Dbl_iszero_exponentmantissa(opnd3p1,opnd3p2)) { 992 if (Is_rounding_mode(ROUNDMINUS)) { 993 Dbl_or_signs(opnd3p1,resultp1); 994 } else { 995 Dbl_and_signs(opnd3p1,resultp1); 996 } 997 } 998 /* 999 * Now let's check for trapped underflow case. 1000 */ 1001 else if (Dbl_iszero_exponent(opnd3p1) && 1002 Is_underflowtrap_enabled()) { 1003 /* need to normalize results mantissa */ 1004 sign_save = Dbl_signextendedsign(opnd3p1); 1005 result_exponent = 0; 1006 Dbl_leftshiftby1(opnd3p1,opnd3p2); 1007 Dbl_normalize(opnd3p1,opnd3p2,result_exponent); 1008 Dbl_set_sign(opnd3p1,/*using*/sign_save); 1009 Dbl_setwrapped_exponent(opnd3p1,result_exponent, 1010 unfl); 1011 Dbl_copytoptr(opnd3p1,opnd3p2,dstptr); 1012 /* inexact = FALSE */ 1013 return(OPC_2E_UNDERFLOWEXCEPTION); 1014 } 1015 Dbl_copytoptr(opnd3p1,opnd3p2,dstptr); 1016 return(NOEXCEPTION); 1017 } 1018 /* is denormalized; want to normalize */ 1019 Dbl_clear_signexponent(opnd2p1); 1020 Dbl_leftshiftby1(opnd2p1,opnd2p2); 1021 Dbl_normalize(opnd2p1,opnd2p2,mpy_exponent); 1022 } 1023 1024 /* Multiply the first two source mantissas together */ 1025 1026 /* 1027 * The intermediate result will be kept in tmpres, 1028 * which needs enough room for 106 bits of mantissa, 1029 * so lets call it a Double extended. 1030 */ 1031 Dblext_setzero(tmpresp1,tmpresp2,tmpresp3,tmpresp4); 1032 1033 /* 1034 * Four bits at a time are inspected in each loop, and a 1035 * simple shift and add multiply algorithm is used. 1036 */ 1037 for (count = DBL_P-1; count >= 0; count -= 4) { 1038 Dblext_rightshiftby4(tmpresp1,tmpresp2,tmpresp3,tmpresp4); 1039 if (Dbit28p2(opnd1p2)) { 1040 /* Fourword_add should be an ADD followed by 3 ADDC's */ 1041 Fourword_add(tmpresp1, tmpresp2, tmpresp3, tmpresp4, 1042 opnd2p1<<3 | opnd2p2>>29, opnd2p2<<3, 0, 0); 1043 } 1044 if (Dbit29p2(opnd1p2)) { 1045 Fourword_add(tmpresp1, tmpresp2, tmpresp3, tmpresp4, 1046 opnd2p1<<2 | opnd2p2>>30, opnd2p2<<2, 0, 0); 1047 } 1048 if (Dbit30p2(opnd1p2)) { 1049 Fourword_add(tmpresp1, tmpresp2, tmpresp3, tmpresp4, 1050 opnd2p1<<1 | opnd2p2>>31, opnd2p2<<1, 0, 0); 1051 } 1052 if (Dbit31p2(opnd1p2)) { 1053 Fourword_add(tmpresp1, tmpresp2, tmpresp3, tmpresp4, 1054 opnd2p1, opnd2p2, 0, 0); 1055 } 1056 Dbl_rightshiftby4(opnd1p1,opnd1p2); 1057 } 1058 if (Is_dexthiddenoverflow(tmpresp1)) { 1059 /* result mantissa >= 2 (mantissa overflow) */ 1060 mpy_exponent++; 1061 Dblext_rightshiftby1(tmpresp1,tmpresp2,tmpresp3,tmpresp4); 1062 } 1063 1064 /* 1065 * Restore the sign of the mpy result which was saved in resultp1. 1066 * The exponent will continue to be kept in mpy_exponent. 1067 */ 1068 Dblext_set_sign(tmpresp1,Dbl_sign(resultp1)); 1069 1070 /* 1071 * No rounding is required, since the result of the multiply 1072 * is exact in the extended format. 1073 */ 1074 1075 /* 1076 * Now we are ready to perform the add portion of the operation. 1077 * 1078 * The exponents need to be kept as integers for now, since the 1079 * multiply result might not fit into the exponent field. We 1080 * can't overflow or underflow because of this yet, since the 1081 * add could bring the final result back into range. 1082 */ 1083 add_exponent = Dbl_exponent(opnd3p1); 1084 1085 /* 1086 * Check for denormalized or zero add operand. 1087 */ 1088 if (add_exponent == 0) { 1089 /* check for zero */ 1090 if (Dbl_iszero_mantissa(opnd3p1,opnd3p2)) { 1091 /* right is zero */ 1092 /* Left can't be zero and must be result. 1093 * 1094 * The final result is now in tmpres and mpy_exponent, 1095 * and needs to be rounded and squeezed back into 1096 * double precision format from double extended. 1097 */ 1098 result_exponent = mpy_exponent; 1099 Dblext_copy(tmpresp1,tmpresp2,tmpresp3,tmpresp4, 1100 resultp1,resultp2,resultp3,resultp4); 1101 sign_save = Dbl_signextendedsign(resultp1);/*save sign*/ 1102 goto round; 1103 } 1104 1105 /* 1106 * Neither are zeroes. 1107 * Adjust exponent and normalize add operand. 1108 */ 1109 sign_save = Dbl_signextendedsign(opnd3p1); /* save sign */ 1110 Dbl_clear_signexponent(opnd3p1); 1111 Dbl_leftshiftby1(opnd3p1,opnd3p2); 1112 Dbl_normalize(opnd3p1,opnd3p2,add_exponent); 1113 Dbl_set_sign(opnd3p1,sign_save); /* restore sign */ 1114 } else { 1115 Dbl_clear_exponent_set_hidden(opnd3p1); 1116 } 1117 /* 1118 * Copy opnd3 to the double extended variable called right. 1119 */ 1120 Dbl_copyto_dblext(opnd3p1,opnd3p2,rightp1,rightp2,rightp3,rightp4); 1121 1122 /* 1123 * A zero "save" helps discover equal operands (for later), 1124 * and is used in swapping operands (if needed). 1125 */ 1126 Dblext_xortointp1(tmpresp1,rightp1,/*to*/save); 1127 1128 /* 1129 * Compare magnitude of operands. 1130 */ 1131 Dblext_copytoint_exponentmantissap1(tmpresp1,signlessleft1); 1132 Dblext_copytoint_exponentmantissap1(rightp1,signlessright1); 1133 if (mpy_exponent < add_exponent || mpy_exponent == add_exponent && 1134 Dblext_ismagnitudeless(tmpresp2,rightp2,signlessleft1,signlessright1)){ 1135 /* 1136 * Set the left operand to the larger one by XOR swap. 1137 * First finish the first word "save". 1138 */ 1139 Dblext_xorfromintp1(save,rightp1,/*to*/rightp1); 1140 Dblext_xorfromintp1(save,tmpresp1,/*to*/tmpresp1); 1141 Dblext_swap_lower(tmpresp2,tmpresp3,tmpresp4, 1142 rightp2,rightp3,rightp4); 1143 /* also setup exponents used in rest of routine */ 1144 diff_exponent = add_exponent - mpy_exponent; 1145 result_exponent = add_exponent; 1146 } else { 1147 /* also setup exponents used in rest of routine */ 1148 diff_exponent = mpy_exponent - add_exponent; 1149 result_exponent = mpy_exponent; 1150 } 1151 /* Invariant: left is not smaller than right. */ 1152 1153 /* 1154 * Special case alignment of operands that would force alignment 1155 * beyond the extent of the extension. A further optimization 1156 * could special case this but only reduces the path length for 1157 * this infrequent case. 1158 */ 1159 if (diff_exponent > DBLEXT_THRESHOLD) { 1160 diff_exponent = DBLEXT_THRESHOLD; 1161 } 1162 1163 /* Align right operand by shifting it to the right */ 1164 Dblext_clear_sign(rightp1); 1165 Dblext_right_align(rightp1,rightp2,rightp3,rightp4, 1166 /*shifted by*/diff_exponent); 1167 1168 /* Treat sum and difference of the operands separately. */ 1169 if ((int)save < 0) { 1170 /* 1171 * Difference of the two operands. Overflow can occur if the 1172 * multiply overflowed. A borrow can occur out of the hidden 1173 * bit and force a post normalization phase. 1174 */ 1175 Dblext_subtract(tmpresp1,tmpresp2,tmpresp3,tmpresp4, 1176 rightp1,rightp2,rightp3,rightp4, 1177 resultp1,resultp2,resultp3,resultp4); 1178 sign_save = Dbl_signextendedsign(resultp1); 1179 if (Dbl_iszero_hidden(resultp1)) { 1180 /* Handle normalization */ 1181 /* A straightforward algorithm would now shift the 1182 * result and extension left until the hidden bit 1183 * becomes one. Not all of the extension bits need 1184 * participate in the shift. Only the two most 1185 * significant bits (round and guard) are needed. 1186 * If only a single shift is needed then the guard 1187 * bit becomes a significant low order bit and the 1188 * extension must participate in the rounding. 1189 * If more than a single shift is needed, then all 1190 * bits to the right of the guard bit are zeros, 1191 * and the guard bit may or may not be zero. */ 1192 Dblext_leftshiftby1(resultp1,resultp2,resultp3, 1193 resultp4); 1194 1195 /* Need to check for a zero result. The sign and 1196 * exponent fields have already been zeroed. The more 1197 * efficient test of the full object can be used. 1198 */ 1199 if (Dblext_iszero(resultp1,resultp2,resultp3,resultp4)) { 1200 /* Must have been "x-x" or "x+(-x)". */ 1201 if (Is_rounding_mode(ROUNDMINUS)) 1202 Dbl_setone_sign(resultp1); 1203 Dbl_copytoptr(resultp1,resultp2,dstptr); 1204 return(NOEXCEPTION); 1205 } 1206 result_exponent--; 1207 1208 /* Look to see if normalization is finished. */ 1209 if (Dbl_isone_hidden(resultp1)) { 1210 /* No further normalization is needed */ 1211 goto round; 1212 } 1213 1214 /* Discover first one bit to determine shift amount. 1215 * Use a modified binary search. We have already 1216 * shifted the result one position right and still 1217 * not found a one so the remainder of the extension 1218 * must be zero and simplifies rounding. */ 1219 /* Scan bytes */ 1220 while (Dbl_iszero_hiddenhigh7mantissa(resultp1)) { 1221 Dblext_leftshiftby8(resultp1,resultp2,resultp3,resultp4); 1222 result_exponent -= 8; 1223 } 1224 /* Now narrow it down to the nibble */ 1225 if (Dbl_iszero_hiddenhigh3mantissa(resultp1)) { 1226 /* The lower nibble contains the 1227 * normalizing one */ 1228 Dblext_leftshiftby4(resultp1,resultp2,resultp3,resultp4); 1229 result_exponent -= 4; 1230 } 1231 /* Select case where first bit is set (already 1232 * normalized) otherwise select the proper shift. */ 1233 jumpsize = Dbl_hiddenhigh3mantissa(resultp1); 1234 if (jumpsize <= 7) switch(jumpsize) { 1235 case 1: 1236 Dblext_leftshiftby3(resultp1,resultp2,resultp3, 1237 resultp4); 1238 result_exponent -= 3; 1239 break; 1240 case 2: 1241 case 3: 1242 Dblext_leftshiftby2(resultp1,resultp2,resultp3, 1243 resultp4); 1244 result_exponent -= 2; 1245 break; 1246 case 4: 1247 case 5: 1248 case 6: 1249 case 7: 1250 Dblext_leftshiftby1(resultp1,resultp2,resultp3, 1251 resultp4); 1252 result_exponent -= 1; 1253 break; 1254 } 1255 } /* end if (hidden...)... */ 1256 /* Fall through and round */ 1257 } /* end if (save < 0)... */ 1258 else { 1259 /* Add magnitudes */ 1260 Dblext_addition(tmpresp1,tmpresp2,tmpresp3,tmpresp4, 1261 rightp1,rightp2,rightp3,rightp4, 1262 /*to*/resultp1,resultp2,resultp3,resultp4); 1263 sign_save = Dbl_signextendedsign(resultp1); 1264 if (Dbl_isone_hiddenoverflow(resultp1)) { 1265 /* Prenormalization required. */ 1266 Dblext_arithrightshiftby1(resultp1,resultp2,resultp3, 1267 resultp4); 1268 result_exponent++; 1269 } /* end if hiddenoverflow... */ 1270 } /* end else ...add magnitudes... */ 1271 1272 /* Round the result. If the extension and lower two words are 1273 * all zeros, then the result is exact. Otherwise round in the 1274 * correct direction. Underflow is possible. If a postnormalization 1275 * is necessary, then the mantissa is all zeros so no shift is needed. 1276 */ 1277 round: 1278 if (result_exponent <= 0 && !Is_underflowtrap_enabled()) { 1279 Dblext_denormalize(resultp1,resultp2,resultp3,resultp4, 1280 result_exponent,is_tiny); 1281 } 1282 Dbl_set_sign(resultp1,/*using*/sign_save); 1283 if (Dblext_isnotzero_mantissap3(resultp3) || 1284 Dblext_isnotzero_mantissap4(resultp4)) { 1285 inexact = TRUE; 1286 switch(Rounding_mode()) { 1287 case ROUNDNEAREST: /* The default. */ 1288 if (Dblext_isone_highp3(resultp3)) { 1289 /* at least 1/2 ulp */ 1290 if (Dblext_isnotzero_low31p3(resultp3) || 1291 Dblext_isnotzero_mantissap4(resultp4) || 1292 Dblext_isone_lowp2(resultp2)) { 1293 /* either exactly half way and odd or 1294 * more than 1/2ulp */ 1295 Dbl_increment(resultp1,resultp2); 1296 } 1297 } 1298 break; 1299 1300 case ROUNDPLUS: 1301 if (Dbl_iszero_sign(resultp1)) { 1302 /* Round up positive results */ 1303 Dbl_increment(resultp1,resultp2); 1304 } 1305 break; 1306 1307 case ROUNDMINUS: 1308 if (Dbl_isone_sign(resultp1)) { 1309 /* Round down negative results */ 1310 Dbl_increment(resultp1,resultp2); 1311 } 1312 1313 case ROUNDZERO:; 1314 /* truncate is simple */ 1315 } /* end switch... */ 1316 if (Dbl_isone_hiddenoverflow(resultp1)) result_exponent++; 1317 } 1318 if (result_exponent >= DBL_INFINITY_EXPONENT) { 1319 /* Overflow */ 1320 if (Is_overflowtrap_enabled()) { 1321 /* 1322 * Adjust bias of result 1323 */ 1324 Dbl_setwrapped_exponent(resultp1,result_exponent,ovfl); 1325 Dbl_copytoptr(resultp1,resultp2,dstptr); 1326 if (inexact) 1327 if (Is_inexacttrap_enabled()) 1328 return (OPC_2E_OVERFLOWEXCEPTION | 1329 OPC_2E_INEXACTEXCEPTION); 1330 else Set_inexactflag(); 1331 return (OPC_2E_OVERFLOWEXCEPTION); 1332 } 1333 inexact = TRUE; 1334 Set_overflowflag(); 1335 Dbl_setoverflow(resultp1,resultp2); 1336 } else if (result_exponent <= 0) { /* underflow case */ 1337 if (Is_underflowtrap_enabled()) { 1338 /* 1339 * Adjust bias of result 1340 */ 1341 Dbl_setwrapped_exponent(resultp1,result_exponent,unfl); 1342 Dbl_copytoptr(resultp1,resultp2,dstptr); 1343 if (inexact) 1344 if (Is_inexacttrap_enabled()) 1345 return (OPC_2E_UNDERFLOWEXCEPTION | 1346 OPC_2E_INEXACTEXCEPTION); 1347 else Set_inexactflag(); 1348 return(OPC_2E_UNDERFLOWEXCEPTION); 1349 } 1350 else if (inexact && is_tiny) Set_underflowflag(); 1351 } 1352 else Dbl_set_exponent(resultp1,result_exponent); 1353 Dbl_copytoptr(resultp1,resultp2,dstptr); 1354 if (inexact) 1355 if (Is_inexacttrap_enabled()) return(OPC_2E_INEXACTEXCEPTION); 1356 else Set_inexactflag(); 1357 return(NOEXCEPTION); 1358 } 1359 1360 /* 1361 * Single Floating-point Multiply Fused Add 1362 */ 1363 1364 sgl_fmpyfadd(src1ptr,src2ptr,src3ptr,status,dstptr) 1365 1366 sgl_floating_point *src1ptr, *src2ptr, *src3ptr, *dstptr; 1367 unsigned int *status; 1368 { 1369 unsigned int opnd1, opnd2, opnd3; 1370 register unsigned int tmpresp1, tmpresp2; 1371 unsigned int rightp1, rightp2; 1372 unsigned int resultp1, resultp2 = 0; 1373 register int mpy_exponent, add_exponent, count; 1374 boolean inexact = FALSE, is_tiny = FALSE; 1375 1376 unsigned int signlessleft1, signlessright1, save; 1377 register int result_exponent, diff_exponent; 1378 int sign_save, jumpsize; 1379 1380 Sgl_copyfromptr(src1ptr,opnd1); 1381 Sgl_copyfromptr(src2ptr,opnd2); 1382 Sgl_copyfromptr(src3ptr,opnd3); 1383 1384 /* 1385 * set sign bit of result of multiply 1386 */ 1387 if (Sgl_sign(opnd1) ^ Sgl_sign(opnd2)) 1388 Sgl_setnegativezero(resultp1); 1389 else Sgl_setzero(resultp1); 1390 1391 /* 1392 * Generate multiply exponent 1393 */ 1394 mpy_exponent = Sgl_exponent(opnd1) + Sgl_exponent(opnd2) - SGL_BIAS; 1395 1396 /* 1397 * check first operand for NaN's or infinity 1398 */ 1399 if (Sgl_isinfinity_exponent(opnd1)) { 1400 if (Sgl_iszero_mantissa(opnd1)) { 1401 if (Sgl_isnotnan(opnd2) && Sgl_isnotnan(opnd3)) { 1402 if (Sgl_iszero_exponentmantissa(opnd2)) { 1403 /* 1404 * invalid since operands are infinity 1405 * and zero 1406 */ 1407 if (Is_invalidtrap_enabled()) 1408 return(OPC_2E_INVALIDEXCEPTION); 1409 Set_invalidflag(); 1410 Sgl_makequietnan(resultp1); 1411 Sgl_copytoptr(resultp1,dstptr); 1412 return(NOEXCEPTION); 1413 } 1414 /* 1415 * Check third operand for infinity with a 1416 * sign opposite of the multiply result 1417 */ 1418 if (Sgl_isinfinity(opnd3) && 1419 (Sgl_sign(resultp1) ^ Sgl_sign(opnd3))) { 1420 /* 1421 * invalid since attempting a magnitude 1422 * subtraction of infinities 1423 */ 1424 if (Is_invalidtrap_enabled()) 1425 return(OPC_2E_INVALIDEXCEPTION); 1426 Set_invalidflag(); 1427 Sgl_makequietnan(resultp1); 1428 Sgl_copytoptr(resultp1,dstptr); 1429 return(NOEXCEPTION); 1430 } 1431 1432 /* 1433 * return infinity 1434 */ 1435 Sgl_setinfinity_exponentmantissa(resultp1); 1436 Sgl_copytoptr(resultp1,dstptr); 1437 return(NOEXCEPTION); 1438 } 1439 } 1440 else { 1441 /* 1442 * is NaN; signaling or quiet? 1443 */ 1444 if (Sgl_isone_signaling(opnd1)) { 1445 /* trap if INVALIDTRAP enabled */ 1446 if (Is_invalidtrap_enabled()) 1447 return(OPC_2E_INVALIDEXCEPTION); 1448 /* make NaN quiet */ 1449 Set_invalidflag(); 1450 Sgl_set_quiet(opnd1); 1451 } 1452 /* 1453 * is second operand a signaling NaN? 1454 */ 1455 else if (Sgl_is_signalingnan(opnd2)) { 1456 /* trap if INVALIDTRAP enabled */ 1457 if (Is_invalidtrap_enabled()) 1458 return(OPC_2E_INVALIDEXCEPTION); 1459 /* make NaN quiet */ 1460 Set_invalidflag(); 1461 Sgl_set_quiet(opnd2); 1462 Sgl_copytoptr(opnd2,dstptr); 1463 return(NOEXCEPTION); 1464 } 1465 /* 1466 * is third operand a signaling NaN? 1467 */ 1468 else if (Sgl_is_signalingnan(opnd3)) { 1469 /* trap if INVALIDTRAP enabled */ 1470 if (Is_invalidtrap_enabled()) 1471 return(OPC_2E_INVALIDEXCEPTION); 1472 /* make NaN quiet */ 1473 Set_invalidflag(); 1474 Sgl_set_quiet(opnd3); 1475 Sgl_copytoptr(opnd3,dstptr); 1476 return(NOEXCEPTION); 1477 } 1478 /* 1479 * return quiet NaN 1480 */ 1481 Sgl_copytoptr(opnd1,dstptr); 1482 return(NOEXCEPTION); 1483 } 1484 } 1485 1486 /* 1487 * check second operand for NaN's or infinity 1488 */ 1489 if (Sgl_isinfinity_exponent(opnd2)) { 1490 if (Sgl_iszero_mantissa(opnd2)) { 1491 if (Sgl_isnotnan(opnd3)) { 1492 if (Sgl_iszero_exponentmantissa(opnd1)) { 1493 /* 1494 * invalid since multiply operands are 1495 * zero & infinity 1496 */ 1497 if (Is_invalidtrap_enabled()) 1498 return(OPC_2E_INVALIDEXCEPTION); 1499 Set_invalidflag(); 1500 Sgl_makequietnan(opnd2); 1501 Sgl_copytoptr(opnd2,dstptr); 1502 return(NOEXCEPTION); 1503 } 1504 1505 /* 1506 * Check third operand for infinity with a 1507 * sign opposite of the multiply result 1508 */ 1509 if (Sgl_isinfinity(opnd3) && 1510 (Sgl_sign(resultp1) ^ Sgl_sign(opnd3))) { 1511 /* 1512 * invalid since attempting a magnitude 1513 * subtraction of infinities 1514 */ 1515 if (Is_invalidtrap_enabled()) 1516 return(OPC_2E_INVALIDEXCEPTION); 1517 Set_invalidflag(); 1518 Sgl_makequietnan(resultp1); 1519 Sgl_copytoptr(resultp1,dstptr); 1520 return(NOEXCEPTION); 1521 } 1522 1523 /* 1524 * return infinity 1525 */ 1526 Sgl_setinfinity_exponentmantissa(resultp1); 1527 Sgl_copytoptr(resultp1,dstptr); 1528 return(NOEXCEPTION); 1529 } 1530 } 1531 else { 1532 /* 1533 * is NaN; signaling or quiet? 1534 */ 1535 if (Sgl_isone_signaling(opnd2)) { 1536 /* trap if INVALIDTRAP enabled */ 1537 if (Is_invalidtrap_enabled()) 1538 return(OPC_2E_INVALIDEXCEPTION); 1539 /* make NaN quiet */ 1540 Set_invalidflag(); 1541 Sgl_set_quiet(opnd2); 1542 } 1543 /* 1544 * is third operand a signaling NaN? 1545 */ 1546 else if (Sgl_is_signalingnan(opnd3)) { 1547 /* trap if INVALIDTRAP enabled */ 1548 if (Is_invalidtrap_enabled()) 1549 return(OPC_2E_INVALIDEXCEPTION); 1550 /* make NaN quiet */ 1551 Set_invalidflag(); 1552 Sgl_set_quiet(opnd3); 1553 Sgl_copytoptr(opnd3,dstptr); 1554 return(NOEXCEPTION); 1555 } 1556 /* 1557 * return quiet NaN 1558 */ 1559 Sgl_copytoptr(opnd2,dstptr); 1560 return(NOEXCEPTION); 1561 } 1562 } 1563 1564 /* 1565 * check third operand for NaN's or infinity 1566 */ 1567 if (Sgl_isinfinity_exponent(opnd3)) { 1568 if (Sgl_iszero_mantissa(opnd3)) { 1569 /* return infinity */ 1570 Sgl_copytoptr(opnd3,dstptr); 1571 return(NOEXCEPTION); 1572 } else { 1573 /* 1574 * is NaN; signaling or quiet? 1575 */ 1576 if (Sgl_isone_signaling(opnd3)) { 1577 /* trap if INVALIDTRAP enabled */ 1578 if (Is_invalidtrap_enabled()) 1579 return(OPC_2E_INVALIDEXCEPTION); 1580 /* make NaN quiet */ 1581 Set_invalidflag(); 1582 Sgl_set_quiet(opnd3); 1583 } 1584 /* 1585 * return quiet NaN 1586 */ 1587 Sgl_copytoptr(opnd3,dstptr); 1588 return(NOEXCEPTION); 1589 } 1590 } 1591 1592 /* 1593 * Generate multiply mantissa 1594 */ 1595 if (Sgl_isnotzero_exponent(opnd1)) { 1596 /* set hidden bit */ 1597 Sgl_clear_signexponent_set_hidden(opnd1); 1598 } 1599 else { 1600 /* check for zero */ 1601 if (Sgl_iszero_mantissa(opnd1)) { 1602 /* 1603 * Perform the add opnd3 with zero here. 1604 */ 1605 if (Sgl_iszero_exponentmantissa(opnd3)) { 1606 if (Is_rounding_mode(ROUNDMINUS)) { 1607 Sgl_or_signs(opnd3,resultp1); 1608 } else { 1609 Sgl_and_signs(opnd3,resultp1); 1610 } 1611 } 1612 /* 1613 * Now let's check for trapped underflow case. 1614 */ 1615 else if (Sgl_iszero_exponent(opnd3) && 1616 Is_underflowtrap_enabled()) { 1617 /* need to normalize results mantissa */ 1618 sign_save = Sgl_signextendedsign(opnd3); 1619 result_exponent = 0; 1620 Sgl_leftshiftby1(opnd3); 1621 Sgl_normalize(opnd3,result_exponent); 1622 Sgl_set_sign(opnd3,/*using*/sign_save); 1623 Sgl_setwrapped_exponent(opnd3,result_exponent, 1624 unfl); 1625 Sgl_copytoptr(opnd3,dstptr); 1626 /* inexact = FALSE */ 1627 return(OPC_2E_UNDERFLOWEXCEPTION); 1628 } 1629 Sgl_copytoptr(opnd3,dstptr); 1630 return(NOEXCEPTION); 1631 } 1632 /* is denormalized, adjust exponent */ 1633 Sgl_clear_signexponent(opnd1); 1634 Sgl_leftshiftby1(opnd1); 1635 Sgl_normalize(opnd1,mpy_exponent); 1636 } 1637 /* opnd2 needs to have hidden bit set with msb in hidden bit */ 1638 if (Sgl_isnotzero_exponent(opnd2)) { 1639 Sgl_clear_signexponent_set_hidden(opnd2); 1640 } 1641 else { 1642 /* check for zero */ 1643 if (Sgl_iszero_mantissa(opnd2)) { 1644 /* 1645 * Perform the add opnd3 with zero here. 1646 */ 1647 if (Sgl_iszero_exponentmantissa(opnd3)) { 1648 if (Is_rounding_mode(ROUNDMINUS)) { 1649 Sgl_or_signs(opnd3,resultp1); 1650 } else { 1651 Sgl_and_signs(opnd3,resultp1); 1652 } 1653 } 1654 /* 1655 * Now let's check for trapped underflow case. 1656 */ 1657 else if (Sgl_iszero_exponent(opnd3) && 1658 Is_underflowtrap_enabled()) { 1659 /* need to normalize results mantissa */ 1660 sign_save = Sgl_signextendedsign(opnd3); 1661 result_exponent = 0; 1662 Sgl_leftshiftby1(opnd3); 1663 Sgl_normalize(opnd3,result_exponent); 1664 Sgl_set_sign(opnd3,/*using*/sign_save); 1665 Sgl_setwrapped_exponent(opnd3,result_exponent, 1666 unfl); 1667 Sgl_copytoptr(opnd3,dstptr); 1668 /* inexact = FALSE */ 1669 return(OPC_2E_UNDERFLOWEXCEPTION); 1670 } 1671 Sgl_copytoptr(opnd3,dstptr); 1672 return(NOEXCEPTION); 1673 } 1674 /* is denormalized; want to normalize */ 1675 Sgl_clear_signexponent(opnd2); 1676 Sgl_leftshiftby1(opnd2); 1677 Sgl_normalize(opnd2,mpy_exponent); 1678 } 1679 1680 /* Multiply the first two source mantissas together */ 1681 1682 /* 1683 * The intermediate result will be kept in tmpres, 1684 * which needs enough room for 106 bits of mantissa, 1685 * so lets call it a Double extended. 1686 */ 1687 Sglext_setzero(tmpresp1,tmpresp2); 1688 1689 /* 1690 * Four bits at a time are inspected in each loop, and a 1691 * simple shift and add multiply algorithm is used. 1692 */ 1693 for (count = SGL_P-1; count >= 0; count -= 4) { 1694 Sglext_rightshiftby4(tmpresp1,tmpresp2); 1695 if (Sbit28(opnd1)) { 1696 /* Twoword_add should be an ADD followed by 2 ADDC's */ 1697 Twoword_add(tmpresp1, tmpresp2, opnd2<<3, 0); 1698 } 1699 if (Sbit29(opnd1)) { 1700 Twoword_add(tmpresp1, tmpresp2, opnd2<<2, 0); 1701 } 1702 if (Sbit30(opnd1)) { 1703 Twoword_add(tmpresp1, tmpresp2, opnd2<<1, 0); 1704 } 1705 if (Sbit31(opnd1)) { 1706 Twoword_add(tmpresp1, tmpresp2, opnd2, 0); 1707 } 1708 Sgl_rightshiftby4(opnd1); 1709 } 1710 if (Is_sexthiddenoverflow(tmpresp1)) { 1711 /* result mantissa >= 2 (mantissa overflow) */ 1712 mpy_exponent++; 1713 Sglext_rightshiftby4(tmpresp1,tmpresp2); 1714 } else { 1715 Sglext_rightshiftby3(tmpresp1,tmpresp2); 1716 } 1717 1718 /* 1719 * Restore the sign of the mpy result which was saved in resultp1. 1720 * The exponent will continue to be kept in mpy_exponent. 1721 */ 1722 Sglext_set_sign(tmpresp1,Sgl_sign(resultp1)); 1723 1724 /* 1725 * No rounding is required, since the result of the multiply 1726 * is exact in the extended format. 1727 */ 1728 1729 /* 1730 * Now we are ready to perform the add portion of the operation. 1731 * 1732 * The exponents need to be kept as integers for now, since the 1733 * multiply result might not fit into the exponent field. We 1734 * can't overflow or underflow because of this yet, since the 1735 * add could bring the final result back into range. 1736 */ 1737 add_exponent = Sgl_exponent(opnd3); 1738 1739 /* 1740 * Check for denormalized or zero add operand. 1741 */ 1742 if (add_exponent == 0) { 1743 /* check for zero */ 1744 if (Sgl_iszero_mantissa(opnd3)) { 1745 /* right is zero */ 1746 /* Left can't be zero and must be result. 1747 * 1748 * The final result is now in tmpres and mpy_exponent, 1749 * and needs to be rounded and squeezed back into 1750 * double precision format from double extended. 1751 */ 1752 result_exponent = mpy_exponent; 1753 Sglext_copy(tmpresp1,tmpresp2,resultp1,resultp2); 1754 sign_save = Sgl_signextendedsign(resultp1);/*save sign*/ 1755 goto round; 1756 } 1757 1758 /* 1759 * Neither are zeroes. 1760 * Adjust exponent and normalize add operand. 1761 */ 1762 sign_save = Sgl_signextendedsign(opnd3); /* save sign */ 1763 Sgl_clear_signexponent(opnd3); 1764 Sgl_leftshiftby1(opnd3); 1765 Sgl_normalize(opnd3,add_exponent); 1766 Sgl_set_sign(opnd3,sign_save); /* restore sign */ 1767 } else { 1768 Sgl_clear_exponent_set_hidden(opnd3); 1769 } 1770 /* 1771 * Copy opnd3 to the double extended variable called right. 1772 */ 1773 Sgl_copyto_sglext(opnd3,rightp1,rightp2); 1774 1775 /* 1776 * A zero "save" helps discover equal operands (for later), 1777 * and is used in swapping operands (if needed). 1778 */ 1779 Sglext_xortointp1(tmpresp1,rightp1,/*to*/save); 1780 1781 /* 1782 * Compare magnitude of operands. 1783 */ 1784 Sglext_copytoint_exponentmantissa(tmpresp1,signlessleft1); 1785 Sglext_copytoint_exponentmantissa(rightp1,signlessright1); 1786 if (mpy_exponent < add_exponent || mpy_exponent == add_exponent && 1787 Sglext_ismagnitudeless(signlessleft1,signlessright1)) { 1788 /* 1789 * Set the left operand to the larger one by XOR swap. 1790 * First finish the first word "save". 1791 */ 1792 Sglext_xorfromintp1(save,rightp1,/*to*/rightp1); 1793 Sglext_xorfromintp1(save,tmpresp1,/*to*/tmpresp1); 1794 Sglext_swap_lower(tmpresp2,rightp2); 1795 /* also setup exponents used in rest of routine */ 1796 diff_exponent = add_exponent - mpy_exponent; 1797 result_exponent = add_exponent; 1798 } else { 1799 /* also setup exponents used in rest of routine */ 1800 diff_exponent = mpy_exponent - add_exponent; 1801 result_exponent = mpy_exponent; 1802 } 1803 /* Invariant: left is not smaller than right. */ 1804 1805 /* 1806 * Special case alignment of operands that would force alignment 1807 * beyond the extent of the extension. A further optimization 1808 * could special case this but only reduces the path length for 1809 * this infrequent case. 1810 */ 1811 if (diff_exponent > SGLEXT_THRESHOLD) { 1812 diff_exponent = SGLEXT_THRESHOLD; 1813 } 1814 1815 /* Align right operand by shifting it to the right */ 1816 Sglext_clear_sign(rightp1); 1817 Sglext_right_align(rightp1,rightp2,/*shifted by*/diff_exponent); 1818 1819 /* Treat sum and difference of the operands separately. */ 1820 if ((int)save < 0) { 1821 /* 1822 * Difference of the two operands. Overflow can occur if the 1823 * multiply overflowed. A borrow can occur out of the hidden 1824 * bit and force a post normalization phase. 1825 */ 1826 Sglext_subtract(tmpresp1,tmpresp2, rightp1,rightp2, 1827 resultp1,resultp2); 1828 sign_save = Sgl_signextendedsign(resultp1); 1829 if (Sgl_iszero_hidden(resultp1)) { 1830 /* Handle normalization */ 1831 /* A straightforward algorithm would now shift the 1832 * result and extension left until the hidden bit 1833 * becomes one. Not all of the extension bits need 1834 * participate in the shift. Only the two most 1835 * significant bits (round and guard) are needed. 1836 * If only a single shift is needed then the guard 1837 * bit becomes a significant low order bit and the 1838 * extension must participate in the rounding. 1839 * If more than a single shift is needed, then all 1840 * bits to the right of the guard bit are zeros, 1841 * and the guard bit may or may not be zero. */ 1842 Sglext_leftshiftby1(resultp1,resultp2); 1843 1844 /* Need to check for a zero result. The sign and 1845 * exponent fields have already been zeroed. The more 1846 * efficient test of the full object can be used. 1847 */ 1848 if (Sglext_iszero(resultp1,resultp2)) { 1849 /* Must have been "x-x" or "x+(-x)". */ 1850 if (Is_rounding_mode(ROUNDMINUS)) 1851 Sgl_setone_sign(resultp1); 1852 Sgl_copytoptr(resultp1,dstptr); 1853 return(NOEXCEPTION); 1854 } 1855 result_exponent--; 1856 1857 /* Look to see if normalization is finished. */ 1858 if (Sgl_isone_hidden(resultp1)) { 1859 /* No further normalization is needed */ 1860 goto round; 1861 } 1862 1863 /* Discover first one bit to determine shift amount. 1864 * Use a modified binary search. We have already 1865 * shifted the result one position right and still 1866 * not found a one so the remainder of the extension 1867 * must be zero and simplifies rounding. */ 1868 /* Scan bytes */ 1869 while (Sgl_iszero_hiddenhigh7mantissa(resultp1)) { 1870 Sglext_leftshiftby8(resultp1,resultp2); 1871 result_exponent -= 8; 1872 } 1873 /* Now narrow it down to the nibble */ 1874 if (Sgl_iszero_hiddenhigh3mantissa(resultp1)) { 1875 /* The lower nibble contains the 1876 * normalizing one */ 1877 Sglext_leftshiftby4(resultp1,resultp2); 1878 result_exponent -= 4; 1879 } 1880 /* Select case where first bit is set (already 1881 * normalized) otherwise select the proper shift. */ 1882 jumpsize = Sgl_hiddenhigh3mantissa(resultp1); 1883 if (jumpsize <= 7) switch(jumpsize) { 1884 case 1: 1885 Sglext_leftshiftby3(resultp1,resultp2); 1886 result_exponent -= 3; 1887 break; 1888 case 2: 1889 case 3: 1890 Sglext_leftshiftby2(resultp1,resultp2); 1891 result_exponent -= 2; 1892 break; 1893 case 4: 1894 case 5: 1895 case 6: 1896 case 7: 1897 Sglext_leftshiftby1(resultp1,resultp2); 1898 result_exponent -= 1; 1899 break; 1900 } 1901 } /* end if (hidden...)... */ 1902 /* Fall through and round */ 1903 } /* end if (save < 0)... */ 1904 else { 1905 /* Add magnitudes */ 1906 Sglext_addition(tmpresp1,tmpresp2, 1907 rightp1,rightp2, /*to*/resultp1,resultp2); 1908 sign_save = Sgl_signextendedsign(resultp1); 1909 if (Sgl_isone_hiddenoverflow(resultp1)) { 1910 /* Prenormalization required. */ 1911 Sglext_arithrightshiftby1(resultp1,resultp2); 1912 result_exponent++; 1913 } /* end if hiddenoverflow... */ 1914 } /* end else ...add magnitudes... */ 1915 1916 /* Round the result. If the extension and lower two words are 1917 * all zeros, then the result is exact. Otherwise round in the 1918 * correct direction. Underflow is possible. If a postnormalization 1919 * is necessary, then the mantissa is all zeros so no shift is needed. 1920 */ 1921 round: 1922 if (result_exponent <= 0 && !Is_underflowtrap_enabled()) { 1923 Sglext_denormalize(resultp1,resultp2,result_exponent,is_tiny); 1924 } 1925 Sgl_set_sign(resultp1,/*using*/sign_save); 1926 if (Sglext_isnotzero_mantissap2(resultp2)) { 1927 inexact = TRUE; 1928 switch(Rounding_mode()) { 1929 case ROUNDNEAREST: /* The default. */ 1930 if (Sglext_isone_highp2(resultp2)) { 1931 /* at least 1/2 ulp */ 1932 if (Sglext_isnotzero_low31p2(resultp2) || 1933 Sglext_isone_lowp1(resultp1)) { 1934 /* either exactly half way and odd or 1935 * more than 1/2ulp */ 1936 Sgl_increment(resultp1); 1937 } 1938 } 1939 break; 1940 1941 case ROUNDPLUS: 1942 if (Sgl_iszero_sign(resultp1)) { 1943 /* Round up positive results */ 1944 Sgl_increment(resultp1); 1945 } 1946 break; 1947 1948 case ROUNDMINUS: 1949 if (Sgl_isone_sign(resultp1)) { 1950 /* Round down negative results */ 1951 Sgl_increment(resultp1); 1952 } 1953 1954 case ROUNDZERO:; 1955 /* truncate is simple */ 1956 } /* end switch... */ 1957 if (Sgl_isone_hiddenoverflow(resultp1)) result_exponent++; 1958 } 1959 if (result_exponent >= SGL_INFINITY_EXPONENT) { 1960 /* Overflow */ 1961 if (Is_overflowtrap_enabled()) { 1962 /* 1963 * Adjust bias of result 1964 */ 1965 Sgl_setwrapped_exponent(resultp1,result_exponent,ovfl); 1966 Sgl_copytoptr(resultp1,dstptr); 1967 if (inexact) 1968 if (Is_inexacttrap_enabled()) 1969 return (OPC_2E_OVERFLOWEXCEPTION | 1970 OPC_2E_INEXACTEXCEPTION); 1971 else Set_inexactflag(); 1972 return (OPC_2E_OVERFLOWEXCEPTION); 1973 } 1974 inexact = TRUE; 1975 Set_overflowflag(); 1976 Sgl_setoverflow(resultp1); 1977 } else if (result_exponent <= 0) { /* underflow case */ 1978 if (Is_underflowtrap_enabled()) { 1979 /* 1980 * Adjust bias of result 1981 */ 1982 Sgl_setwrapped_exponent(resultp1,result_exponent,unfl); 1983 Sgl_copytoptr(resultp1,dstptr); 1984 if (inexact) 1985 if (Is_inexacttrap_enabled()) 1986 return (OPC_2E_UNDERFLOWEXCEPTION | 1987 OPC_2E_INEXACTEXCEPTION); 1988 else Set_inexactflag(); 1989 return(OPC_2E_UNDERFLOWEXCEPTION); 1990 } 1991 else if (inexact && is_tiny) Set_underflowflag(); 1992 } 1993 else Sgl_set_exponent(resultp1,result_exponent); 1994 Sgl_copytoptr(resultp1,dstptr); 1995 if (inexact) 1996 if (Is_inexacttrap_enabled()) return(OPC_2E_INEXACTEXCEPTION); 1997 else Set_inexactflag(); 1998 return(NOEXCEPTION); 1999 } 2000 2001 /* 2002 * Single Floating-point Multiply Negate Fused Add 2003 */ 2004 2005 sgl_fmpynfadd(src1ptr,src2ptr,src3ptr,status,dstptr) 2006 2007 sgl_floating_point *src1ptr, *src2ptr, *src3ptr, *dstptr; 2008 unsigned int *status; 2009 { 2010 unsigned int opnd1, opnd2, opnd3; 2011 register unsigned int tmpresp1, tmpresp2; 2012 unsigned int rightp1, rightp2; 2013 unsigned int resultp1, resultp2 = 0; 2014 register int mpy_exponent, add_exponent, count; 2015 boolean inexact = FALSE, is_tiny = FALSE; 2016 2017 unsigned int signlessleft1, signlessright1, save; 2018 register int result_exponent, diff_exponent; 2019 int sign_save, jumpsize; 2020 2021 Sgl_copyfromptr(src1ptr,opnd1); 2022 Sgl_copyfromptr(src2ptr,opnd2); 2023 Sgl_copyfromptr(src3ptr,opnd3); 2024 2025 /* 2026 * set sign bit of result of multiply 2027 */ 2028 if (Sgl_sign(opnd1) ^ Sgl_sign(opnd2)) 2029 Sgl_setzero(resultp1); 2030 else 2031 Sgl_setnegativezero(resultp1); 2032 2033 /* 2034 * Generate multiply exponent 2035 */ 2036 mpy_exponent = Sgl_exponent(opnd1) + Sgl_exponent(opnd2) - SGL_BIAS; 2037 2038 /* 2039 * check first operand for NaN's or infinity 2040 */ 2041 if (Sgl_isinfinity_exponent(opnd1)) { 2042 if (Sgl_iszero_mantissa(opnd1)) { 2043 if (Sgl_isnotnan(opnd2) && Sgl_isnotnan(opnd3)) { 2044 if (Sgl_iszero_exponentmantissa(opnd2)) { 2045 /* 2046 * invalid since operands are infinity 2047 * and zero 2048 */ 2049 if (Is_invalidtrap_enabled()) 2050 return(OPC_2E_INVALIDEXCEPTION); 2051 Set_invalidflag(); 2052 Sgl_makequietnan(resultp1); 2053 Sgl_copytoptr(resultp1,dstptr); 2054 return(NOEXCEPTION); 2055 } 2056 /* 2057 * Check third operand for infinity with a 2058 * sign opposite of the multiply result 2059 */ 2060 if (Sgl_isinfinity(opnd3) && 2061 (Sgl_sign(resultp1) ^ Sgl_sign(opnd3))) { 2062 /* 2063 * invalid since attempting a magnitude 2064 * subtraction of infinities 2065 */ 2066 if (Is_invalidtrap_enabled()) 2067 return(OPC_2E_INVALIDEXCEPTION); 2068 Set_invalidflag(); 2069 Sgl_makequietnan(resultp1); 2070 Sgl_copytoptr(resultp1,dstptr); 2071 return(NOEXCEPTION); 2072 } 2073 2074 /* 2075 * return infinity 2076 */ 2077 Sgl_setinfinity_exponentmantissa(resultp1); 2078 Sgl_copytoptr(resultp1,dstptr); 2079 return(NOEXCEPTION); 2080 } 2081 } 2082 else { 2083 /* 2084 * is NaN; signaling or quiet? 2085 */ 2086 if (Sgl_isone_signaling(opnd1)) { 2087 /* trap if INVALIDTRAP enabled */ 2088 if (Is_invalidtrap_enabled()) 2089 return(OPC_2E_INVALIDEXCEPTION); 2090 /* make NaN quiet */ 2091 Set_invalidflag(); 2092 Sgl_set_quiet(opnd1); 2093 } 2094 /* 2095 * is second operand a signaling NaN? 2096 */ 2097 else if (Sgl_is_signalingnan(opnd2)) { 2098 /* trap if INVALIDTRAP enabled */ 2099 if (Is_invalidtrap_enabled()) 2100 return(OPC_2E_INVALIDEXCEPTION); 2101 /* make NaN quiet */ 2102 Set_invalidflag(); 2103 Sgl_set_quiet(opnd2); 2104 Sgl_copytoptr(opnd2,dstptr); 2105 return(NOEXCEPTION); 2106 } 2107 /* 2108 * is third operand a signaling NaN? 2109 */ 2110 else if (Sgl_is_signalingnan(opnd3)) { 2111 /* trap if INVALIDTRAP enabled */ 2112 if (Is_invalidtrap_enabled()) 2113 return(OPC_2E_INVALIDEXCEPTION); 2114 /* make NaN quiet */ 2115 Set_invalidflag(); 2116 Sgl_set_quiet(opnd3); 2117 Sgl_copytoptr(opnd3,dstptr); 2118 return(NOEXCEPTION); 2119 } 2120 /* 2121 * return quiet NaN 2122 */ 2123 Sgl_copytoptr(opnd1,dstptr); 2124 return(NOEXCEPTION); 2125 } 2126 } 2127 2128 /* 2129 * check second operand for NaN's or infinity 2130 */ 2131 if (Sgl_isinfinity_exponent(opnd2)) { 2132 if (Sgl_iszero_mantissa(opnd2)) { 2133 if (Sgl_isnotnan(opnd3)) { 2134 if (Sgl_iszero_exponentmantissa(opnd1)) { 2135 /* 2136 * invalid since multiply operands are 2137 * zero & infinity 2138 */ 2139 if (Is_invalidtrap_enabled()) 2140 return(OPC_2E_INVALIDEXCEPTION); 2141 Set_invalidflag(); 2142 Sgl_makequietnan(opnd2); 2143 Sgl_copytoptr(opnd2,dstptr); 2144 return(NOEXCEPTION); 2145 } 2146 2147 /* 2148 * Check third operand for infinity with a 2149 * sign opposite of the multiply result 2150 */ 2151 if (Sgl_isinfinity(opnd3) && 2152 (Sgl_sign(resultp1) ^ Sgl_sign(opnd3))) { 2153 /* 2154 * invalid since attempting a magnitude 2155 * subtraction of infinities 2156 */ 2157 if (Is_invalidtrap_enabled()) 2158 return(OPC_2E_INVALIDEXCEPTION); 2159 Set_invalidflag(); 2160 Sgl_makequietnan(resultp1); 2161 Sgl_copytoptr(resultp1,dstptr); 2162 return(NOEXCEPTION); 2163 } 2164 2165 /* 2166 * return infinity 2167 */ 2168 Sgl_setinfinity_exponentmantissa(resultp1); 2169 Sgl_copytoptr(resultp1,dstptr); 2170 return(NOEXCEPTION); 2171 } 2172 } 2173 else { 2174 /* 2175 * is NaN; signaling or quiet? 2176 */ 2177 if (Sgl_isone_signaling(opnd2)) { 2178 /* trap if INVALIDTRAP enabled */ 2179 if (Is_invalidtrap_enabled()) 2180 return(OPC_2E_INVALIDEXCEPTION); 2181 /* make NaN quiet */ 2182 Set_invalidflag(); 2183 Sgl_set_quiet(opnd2); 2184 } 2185 /* 2186 * is third operand a signaling NaN? 2187 */ 2188 else if (Sgl_is_signalingnan(opnd3)) { 2189 /* trap if INVALIDTRAP enabled */ 2190 if (Is_invalidtrap_enabled()) 2191 return(OPC_2E_INVALIDEXCEPTION); 2192 /* make NaN quiet */ 2193 Set_invalidflag(); 2194 Sgl_set_quiet(opnd3); 2195 Sgl_copytoptr(opnd3,dstptr); 2196 return(NOEXCEPTION); 2197 } 2198 /* 2199 * return quiet NaN 2200 */ 2201 Sgl_copytoptr(opnd2,dstptr); 2202 return(NOEXCEPTION); 2203 } 2204 } 2205 2206 /* 2207 * check third operand for NaN's or infinity 2208 */ 2209 if (Sgl_isinfinity_exponent(opnd3)) { 2210 if (Sgl_iszero_mantissa(opnd3)) { 2211 /* return infinity */ 2212 Sgl_copytoptr(opnd3,dstptr); 2213 return(NOEXCEPTION); 2214 } else { 2215 /* 2216 * is NaN; signaling or quiet? 2217 */ 2218 if (Sgl_isone_signaling(opnd3)) { 2219 /* trap if INVALIDTRAP enabled */ 2220 if (Is_invalidtrap_enabled()) 2221 return(OPC_2E_INVALIDEXCEPTION); 2222 /* make NaN quiet */ 2223 Set_invalidflag(); 2224 Sgl_set_quiet(opnd3); 2225 } 2226 /* 2227 * return quiet NaN 2228 */ 2229 Sgl_copytoptr(opnd3,dstptr); 2230 return(NOEXCEPTION); 2231 } 2232 } 2233 2234 /* 2235 * Generate multiply mantissa 2236 */ 2237 if (Sgl_isnotzero_exponent(opnd1)) { 2238 /* set hidden bit */ 2239 Sgl_clear_signexponent_set_hidden(opnd1); 2240 } 2241 else { 2242 /* check for zero */ 2243 if (Sgl_iszero_mantissa(opnd1)) { 2244 /* 2245 * Perform the add opnd3 with zero here. 2246 */ 2247 if (Sgl_iszero_exponentmantissa(opnd3)) { 2248 if (Is_rounding_mode(ROUNDMINUS)) { 2249 Sgl_or_signs(opnd3,resultp1); 2250 } else { 2251 Sgl_and_signs(opnd3,resultp1); 2252 } 2253 } 2254 /* 2255 * Now let's check for trapped underflow case. 2256 */ 2257 else if (Sgl_iszero_exponent(opnd3) && 2258 Is_underflowtrap_enabled()) { 2259 /* need to normalize results mantissa */ 2260 sign_save = Sgl_signextendedsign(opnd3); 2261 result_exponent = 0; 2262 Sgl_leftshiftby1(opnd3); 2263 Sgl_normalize(opnd3,result_exponent); 2264 Sgl_set_sign(opnd3,/*using*/sign_save); 2265 Sgl_setwrapped_exponent(opnd3,result_exponent, 2266 unfl); 2267 Sgl_copytoptr(opnd3,dstptr); 2268 /* inexact = FALSE */ 2269 return(OPC_2E_UNDERFLOWEXCEPTION); 2270 } 2271 Sgl_copytoptr(opnd3,dstptr); 2272 return(NOEXCEPTION); 2273 } 2274 /* is denormalized, adjust exponent */ 2275 Sgl_clear_signexponent(opnd1); 2276 Sgl_leftshiftby1(opnd1); 2277 Sgl_normalize(opnd1,mpy_exponent); 2278 } 2279 /* opnd2 needs to have hidden bit set with msb in hidden bit */ 2280 if (Sgl_isnotzero_exponent(opnd2)) { 2281 Sgl_clear_signexponent_set_hidden(opnd2); 2282 } 2283 else { 2284 /* check for zero */ 2285 if (Sgl_iszero_mantissa(opnd2)) { 2286 /* 2287 * Perform the add opnd3 with zero here. 2288 */ 2289 if (Sgl_iszero_exponentmantissa(opnd3)) { 2290 if (Is_rounding_mode(ROUNDMINUS)) { 2291 Sgl_or_signs(opnd3,resultp1); 2292 } else { 2293 Sgl_and_signs(opnd3,resultp1); 2294 } 2295 } 2296 /* 2297 * Now let's check for trapped underflow case. 2298 */ 2299 else if (Sgl_iszero_exponent(opnd3) && 2300 Is_underflowtrap_enabled()) { 2301 /* need to normalize results mantissa */ 2302 sign_save = Sgl_signextendedsign(opnd3); 2303 result_exponent = 0; 2304 Sgl_leftshiftby1(opnd3); 2305 Sgl_normalize(opnd3,result_exponent); 2306 Sgl_set_sign(opnd3,/*using*/sign_save); 2307 Sgl_setwrapped_exponent(opnd3,result_exponent, 2308 unfl); 2309 Sgl_copytoptr(opnd3,dstptr); 2310 /* inexact = FALSE */ 2311 return(OPC_2E_UNDERFLOWEXCEPTION); 2312 } 2313 Sgl_copytoptr(opnd3,dstptr); 2314 return(NOEXCEPTION); 2315 } 2316 /* is denormalized; want to normalize */ 2317 Sgl_clear_signexponent(opnd2); 2318 Sgl_leftshiftby1(opnd2); 2319 Sgl_normalize(opnd2,mpy_exponent); 2320 } 2321 2322 /* Multiply the first two source mantissas together */ 2323 2324 /* 2325 * The intermediate result will be kept in tmpres, 2326 * which needs enough room for 106 bits of mantissa, 2327 * so lets call it a Double extended. 2328 */ 2329 Sglext_setzero(tmpresp1,tmpresp2); 2330 2331 /* 2332 * Four bits at a time are inspected in each loop, and a 2333 * simple shift and add multiply algorithm is used. 2334 */ 2335 for (count = SGL_P-1; count >= 0; count -= 4) { 2336 Sglext_rightshiftby4(tmpresp1,tmpresp2); 2337 if (Sbit28(opnd1)) { 2338 /* Twoword_add should be an ADD followed by 2 ADDC's */ 2339 Twoword_add(tmpresp1, tmpresp2, opnd2<<3, 0); 2340 } 2341 if (Sbit29(opnd1)) { 2342 Twoword_add(tmpresp1, tmpresp2, opnd2<<2, 0); 2343 } 2344 if (Sbit30(opnd1)) { 2345 Twoword_add(tmpresp1, tmpresp2, opnd2<<1, 0); 2346 } 2347 if (Sbit31(opnd1)) { 2348 Twoword_add(tmpresp1, tmpresp2, opnd2, 0); 2349 } 2350 Sgl_rightshiftby4(opnd1); 2351 } 2352 if (Is_sexthiddenoverflow(tmpresp1)) { 2353 /* result mantissa >= 2 (mantissa overflow) */ 2354 mpy_exponent++; 2355 Sglext_rightshiftby4(tmpresp1,tmpresp2); 2356 } else { 2357 Sglext_rightshiftby3(tmpresp1,tmpresp2); 2358 } 2359 2360 /* 2361 * Restore the sign of the mpy result which was saved in resultp1. 2362 * The exponent will continue to be kept in mpy_exponent. 2363 */ 2364 Sglext_set_sign(tmpresp1,Sgl_sign(resultp1)); 2365 2366 /* 2367 * No rounding is required, since the result of the multiply 2368 * is exact in the extended format. 2369 */ 2370 2371 /* 2372 * Now we are ready to perform the add portion of the operation. 2373 * 2374 * The exponents need to be kept as integers for now, since the 2375 * multiply result might not fit into the exponent field. We 2376 * can't overflow or underflow because of this yet, since the 2377 * add could bring the final result back into range. 2378 */ 2379 add_exponent = Sgl_exponent(opnd3); 2380 2381 /* 2382 * Check for denormalized or zero add operand. 2383 */ 2384 if (add_exponent == 0) { 2385 /* check for zero */ 2386 if (Sgl_iszero_mantissa(opnd3)) { 2387 /* right is zero */ 2388 /* Left can't be zero and must be result. 2389 * 2390 * The final result is now in tmpres and mpy_exponent, 2391 * and needs to be rounded and squeezed back into 2392 * double precision format from double extended. 2393 */ 2394 result_exponent = mpy_exponent; 2395 Sglext_copy(tmpresp1,tmpresp2,resultp1,resultp2); 2396 sign_save = Sgl_signextendedsign(resultp1);/*save sign*/ 2397 goto round; 2398 } 2399 2400 /* 2401 * Neither are zeroes. 2402 * Adjust exponent and normalize add operand. 2403 */ 2404 sign_save = Sgl_signextendedsign(opnd3); /* save sign */ 2405 Sgl_clear_signexponent(opnd3); 2406 Sgl_leftshiftby1(opnd3); 2407 Sgl_normalize(opnd3,add_exponent); 2408 Sgl_set_sign(opnd3,sign_save); /* restore sign */ 2409 } else { 2410 Sgl_clear_exponent_set_hidden(opnd3); 2411 } 2412 /* 2413 * Copy opnd3 to the double extended variable called right. 2414 */ 2415 Sgl_copyto_sglext(opnd3,rightp1,rightp2); 2416 2417 /* 2418 * A zero "save" helps discover equal operands (for later), 2419 * and is used in swapping operands (if needed). 2420 */ 2421 Sglext_xortointp1(tmpresp1,rightp1,/*to*/save); 2422 2423 /* 2424 * Compare magnitude of operands. 2425 */ 2426 Sglext_copytoint_exponentmantissa(tmpresp1,signlessleft1); 2427 Sglext_copytoint_exponentmantissa(rightp1,signlessright1); 2428 if (mpy_exponent < add_exponent || mpy_exponent == add_exponent && 2429 Sglext_ismagnitudeless(signlessleft1,signlessright1)) { 2430 /* 2431 * Set the left operand to the larger one by XOR swap. 2432 * First finish the first word "save". 2433 */ 2434 Sglext_xorfromintp1(save,rightp1,/*to*/rightp1); 2435 Sglext_xorfromintp1(save,tmpresp1,/*to*/tmpresp1); 2436 Sglext_swap_lower(tmpresp2,rightp2); 2437 /* also setup exponents used in rest of routine */ 2438 diff_exponent = add_exponent - mpy_exponent; 2439 result_exponent = add_exponent; 2440 } else { 2441 /* also setup exponents used in rest of routine */ 2442 diff_exponent = mpy_exponent - add_exponent; 2443 result_exponent = mpy_exponent; 2444 } 2445 /* Invariant: left is not smaller than right. */ 2446 2447 /* 2448 * Special case alignment of operands that would force alignment 2449 * beyond the extent of the extension. A further optimization 2450 * could special case this but only reduces the path length for 2451 * this infrequent case. 2452 */ 2453 if (diff_exponent > SGLEXT_THRESHOLD) { 2454 diff_exponent = SGLEXT_THRESHOLD; 2455 } 2456 2457 /* Align right operand by shifting it to the right */ 2458 Sglext_clear_sign(rightp1); 2459 Sglext_right_align(rightp1,rightp2,/*shifted by*/diff_exponent); 2460 2461 /* Treat sum and difference of the operands separately. */ 2462 if ((int)save < 0) { 2463 /* 2464 * Difference of the two operands. Overflow can occur if the 2465 * multiply overflowed. A borrow can occur out of the hidden 2466 * bit and force a post normalization phase. 2467 */ 2468 Sglext_subtract(tmpresp1,tmpresp2, rightp1,rightp2, 2469 resultp1,resultp2); 2470 sign_save = Sgl_signextendedsign(resultp1); 2471 if (Sgl_iszero_hidden(resultp1)) { 2472 /* Handle normalization */ 2473 /* A straightforward algorithm would now shift the 2474 * result and extension left until the hidden bit 2475 * becomes one. Not all of the extension bits need 2476 * participate in the shift. Only the two most 2477 * significant bits (round and guard) are needed. 2478 * If only a single shift is needed then the guard 2479 * bit becomes a significant low order bit and the 2480 * extension must participate in the rounding. 2481 * If more than a single shift is needed, then all 2482 * bits to the right of the guard bit are zeros, 2483 * and the guard bit may or may not be zero. */ 2484 Sglext_leftshiftby1(resultp1,resultp2); 2485 2486 /* Need to check for a zero result. The sign and 2487 * exponent fields have already been zeroed. The more 2488 * efficient test of the full object can be used. 2489 */ 2490 if (Sglext_iszero(resultp1,resultp2)) { 2491 /* Must have been "x-x" or "x+(-x)". */ 2492 if (Is_rounding_mode(ROUNDMINUS)) 2493 Sgl_setone_sign(resultp1); 2494 Sgl_copytoptr(resultp1,dstptr); 2495 return(NOEXCEPTION); 2496 } 2497 result_exponent--; 2498 2499 /* Look to see if normalization is finished. */ 2500 if (Sgl_isone_hidden(resultp1)) { 2501 /* No further normalization is needed */ 2502 goto round; 2503 } 2504 2505 /* Discover first one bit to determine shift amount. 2506 * Use a modified binary search. We have already 2507 * shifted the result one position right and still 2508 * not found a one so the remainder of the extension 2509 * must be zero and simplifies rounding. */ 2510 /* Scan bytes */ 2511 while (Sgl_iszero_hiddenhigh7mantissa(resultp1)) { 2512 Sglext_leftshiftby8(resultp1,resultp2); 2513 result_exponent -= 8; 2514 } 2515 /* Now narrow it down to the nibble */ 2516 if (Sgl_iszero_hiddenhigh3mantissa(resultp1)) { 2517 /* The lower nibble contains the 2518 * normalizing one */ 2519 Sglext_leftshiftby4(resultp1,resultp2); 2520 result_exponent -= 4; 2521 } 2522 /* Select case where first bit is set (already 2523 * normalized) otherwise select the proper shift. */ 2524 jumpsize = Sgl_hiddenhigh3mantissa(resultp1); 2525 if (jumpsize <= 7) switch(jumpsize) { 2526 case 1: 2527 Sglext_leftshiftby3(resultp1,resultp2); 2528 result_exponent -= 3; 2529 break; 2530 case 2: 2531 case 3: 2532 Sglext_leftshiftby2(resultp1,resultp2); 2533 result_exponent -= 2; 2534 break; 2535 case 4: 2536 case 5: 2537 case 6: 2538 case 7: 2539 Sglext_leftshiftby1(resultp1,resultp2); 2540 result_exponent -= 1; 2541 break; 2542 } 2543 } /* end if (hidden...)... */ 2544 /* Fall through and round */ 2545 } /* end if (save < 0)... */ 2546 else { 2547 /* Add magnitudes */ 2548 Sglext_addition(tmpresp1,tmpresp2, 2549 rightp1,rightp2, /*to*/resultp1,resultp2); 2550 sign_save = Sgl_signextendedsign(resultp1); 2551 if (Sgl_isone_hiddenoverflow(resultp1)) { 2552 /* Prenormalization required. */ 2553 Sglext_arithrightshiftby1(resultp1,resultp2); 2554 result_exponent++; 2555 } /* end if hiddenoverflow... */ 2556 } /* end else ...add magnitudes... */ 2557 2558 /* Round the result. If the extension and lower two words are 2559 * all zeros, then the result is exact. Otherwise round in the 2560 * correct direction. Underflow is possible. If a postnormalization 2561 * is necessary, then the mantissa is all zeros so no shift is needed. 2562 */ 2563 round: 2564 if (result_exponent <= 0 && !Is_underflowtrap_enabled()) { 2565 Sglext_denormalize(resultp1,resultp2,result_exponent,is_tiny); 2566 } 2567 Sgl_set_sign(resultp1,/*using*/sign_save); 2568 if (Sglext_isnotzero_mantissap2(resultp2)) { 2569 inexact = TRUE; 2570 switch(Rounding_mode()) { 2571 case ROUNDNEAREST: /* The default. */ 2572 if (Sglext_isone_highp2(resultp2)) { 2573 /* at least 1/2 ulp */ 2574 if (Sglext_isnotzero_low31p2(resultp2) || 2575 Sglext_isone_lowp1(resultp1)) { 2576 /* either exactly half way and odd or 2577 * more than 1/2ulp */ 2578 Sgl_increment(resultp1); 2579 } 2580 } 2581 break; 2582 2583 case ROUNDPLUS: 2584 if (Sgl_iszero_sign(resultp1)) { 2585 /* Round up positive results */ 2586 Sgl_increment(resultp1); 2587 } 2588 break; 2589 2590 case ROUNDMINUS: 2591 if (Sgl_isone_sign(resultp1)) { 2592 /* Round down negative results */ 2593 Sgl_increment(resultp1); 2594 } 2595 2596 case ROUNDZERO:; 2597 /* truncate is simple */ 2598 } /* end switch... */ 2599 if (Sgl_isone_hiddenoverflow(resultp1)) result_exponent++; 2600 } 2601 if (result_exponent >= SGL_INFINITY_EXPONENT) { 2602 /* Overflow */ 2603 if (Is_overflowtrap_enabled()) { 2604 /* 2605 * Adjust bias of result 2606 */ 2607 Sgl_setwrapped_exponent(resultp1,result_exponent,ovfl); 2608 Sgl_copytoptr(resultp1,dstptr); 2609 if (inexact) 2610 if (Is_inexacttrap_enabled()) 2611 return (OPC_2E_OVERFLOWEXCEPTION | 2612 OPC_2E_INEXACTEXCEPTION); 2613 else Set_inexactflag(); 2614 return (OPC_2E_OVERFLOWEXCEPTION); 2615 } 2616 inexact = TRUE; 2617 Set_overflowflag(); 2618 Sgl_setoverflow(resultp1); 2619 } else if (result_exponent <= 0) { /* underflow case */ 2620 if (Is_underflowtrap_enabled()) { 2621 /* 2622 * Adjust bias of result 2623 */ 2624 Sgl_setwrapped_exponent(resultp1,result_exponent,unfl); 2625 Sgl_copytoptr(resultp1,dstptr); 2626 if (inexact) 2627 if (Is_inexacttrap_enabled()) 2628 return (OPC_2E_UNDERFLOWEXCEPTION | 2629 OPC_2E_INEXACTEXCEPTION); 2630 else Set_inexactflag(); 2631 return(OPC_2E_UNDERFLOWEXCEPTION); 2632 } 2633 else if (inexact && is_tiny) Set_underflowflag(); 2634 } 2635 else Sgl_set_exponent(resultp1,result_exponent); 2636 Sgl_copytoptr(resultp1,dstptr); 2637 if (inexact) 2638 if (Is_inexacttrap_enabled()) return(OPC_2E_INEXACTEXCEPTION); 2639 else Set_inexactflag(); 2640 return(NOEXCEPTION); 2641 } 2642 2643
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.