linux/arch/parisc/math-emu/fmpyfadd.c
<<
>>
Prefs
   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
  44int
  45dbl_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
 706dbl_fmpynfadd(src1ptr,src2ptr,src3ptr,status,dstptr)
 707
 708dbl_floating_point *src1ptr, *src2ptr, *src3ptr, *dstptr;
 709unsigned 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
1364sgl_fmpyfadd(src1ptr,src2ptr,src3ptr,status,dstptr)
1365
1366sgl_floating_point *src1ptr, *src2ptr, *src3ptr, *dstptr;
1367unsigned 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
2005sgl_fmpynfadd(src1ptr,src2ptr,src3ptr,status,dstptr)
2006
2007sgl_floating_point *src1ptr, *src2ptr, *src3ptr, *dstptr;
2008unsigned 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