~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/parisc/math-emu/fmpyfadd.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php