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