Annotation of sys/arch/hppa/spmath/dfsqrt.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: dfsqrt.c,v 1.7 2003/04/10 17:27:58 mickey Exp $ */
2: /*
3: (c) Copyright 1986 HEWLETT-PACKARD COMPANY
4: To anyone who acknowledges that this file is provided "AS IS"
5: without any express or implied warranty:
6: permission to use, copy, modify, and distribute this file
7: for any purpose is hereby granted without fee, provided that
8: the above copyright notice and this notice appears in all
9: copies, and that the name of Hewlett-Packard Company not be
10: used in advertising or publicity pertaining to distribution
11: of the software without specific, written prior permission.
12: Hewlett-Packard Company makes no representations about the
13: suitability of this software for any purpose.
14: */
15: /* @(#)dfsqrt.c: Revision: 1.9.88.1 Date: 93/12/07 15:05:46 */
16:
17: #include "float.h"
18: #include "dbl_float.h"
19:
20: /*
21: * Double Floating-point Square Root
22: */
23:
24: /*ARGSUSED*/
25: int
26: dbl_fsqrt(srcptr, null, dstptr, status)
27: dbl_floating_point *srcptr, *null, *dstptr;
28: unsigned int *status;
29: {
30: register unsigned int srcp1, srcp2, resultp1, resultp2;
31: register unsigned int newbitp1, newbitp2, sump1, sump2;
32: register int src_exponent;
33: register int guardbit = FALSE, even_exponent;
34:
35: Dbl_copyfromptr(srcptr,srcp1,srcp2);
36: /*
37: * check source operand for NaN or infinity
38: */
39: if ((src_exponent = Dbl_exponent(srcp1)) == DBL_INFINITY_EXPONENT) {
40: /*
41: * is signaling NaN?
42: */
43: if (Dbl_isone_signaling(srcp1)) {
44: /* trap if INVALIDTRAP enabled */
45: if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
46: /* make NaN quiet */
47: Set_invalidflag();
48: Dbl_set_quiet(srcp1);
49: }
50: /*
51: * Return quiet NaN or positive infinity.
52: * Fall thru to negative test if negative infinity.
53: */
54: if (Dbl_iszero_sign(srcp1) ||
55: Dbl_isnotzero_mantissa(srcp1,srcp2)) {
56: Dbl_copytoptr(srcp1,srcp2,dstptr);
57: return(NOEXCEPTION);
58: }
59: }
60:
61: /*
62: * check for zero source operand
63: */
64: if (Dbl_iszero_exponentmantissa(srcp1,srcp2)) {
65: Dbl_copytoptr(srcp1,srcp2,dstptr);
66: return(NOEXCEPTION);
67: }
68:
69: /*
70: * check for negative source operand
71: */
72: if (Dbl_isone_sign(srcp1)) {
73: /* trap if INVALIDTRAP enabled */
74: if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
75: /* make NaN quiet */
76: Set_invalidflag();
77: Dbl_makequietnan(srcp1,srcp2);
78: Dbl_copytoptr(srcp1,srcp2,dstptr);
79: return(NOEXCEPTION);
80: }
81:
82: /*
83: * Generate result
84: */
85: if (src_exponent > 0) {
86: even_exponent = Dbl_hidden(srcp1);
87: Dbl_clear_signexponent_set_hidden(srcp1);
88: }
89: else {
90: /* normalize operand */
91: Dbl_clear_signexponent(srcp1);
92: src_exponent++;
93: Dbl_normalize(srcp1,srcp2,src_exponent);
94: even_exponent = src_exponent & 1;
95: }
96: if (even_exponent) {
97: /* exponent is even */
98: /* Add comment here. Explain why odd exponent needs correction */
99: Dbl_leftshiftby1(srcp1,srcp2);
100: }
101: /*
102: * Add comment here. Explain following algorithm.
103: *
104: * Trust me, it works.
105: *
106: */
107: Dbl_setzero(resultp1,resultp2);
108: Dbl_allp1(newbitp1) = 1 << (DBL_P - 32);
109: Dbl_setzero_mantissap2(newbitp2);
110: while (Dbl_isnotzero(newbitp1,newbitp2) && Dbl_isnotzero(srcp1,srcp2)) {
111: Dbl_addition(resultp1,resultp2,newbitp1,newbitp2,sump1,sump2);
112: if(Dbl_isnotgreaterthan(sump1,sump2,srcp1,srcp2)) {
113: Dbl_leftshiftby1(newbitp1,newbitp2);
114: /* update result */
115: Dbl_addition(resultp1,resultp2,newbitp1,newbitp2,
116: resultp1,resultp2);
117: Dbl_subtract(srcp1,srcp2,sump1,sump2,srcp1,srcp2);
118: Dbl_rightshiftby2(newbitp1,newbitp2);
119: }
120: else {
121: Dbl_rightshiftby1(newbitp1,newbitp2);
122: }
123: Dbl_leftshiftby1(srcp1,srcp2);
124: }
125: /* correct exponent for pre-shift */
126: if (even_exponent) {
127: Dbl_rightshiftby1(resultp1,resultp2);
128: }
129:
130: /* check for inexact */
131: if (Dbl_isnotzero(srcp1,srcp2)) {
132: if (!even_exponent & Dbl_islessthan(resultp1,resultp2,srcp1,srcp2)) {
133: Dbl_increment(resultp1,resultp2);
134: }
135: guardbit = Dbl_lowmantissap2(resultp2);
136: Dbl_rightshiftby1(resultp1,resultp2);
137:
138: /* now round result */
139: switch (Rounding_mode()) {
140: case ROUNDPLUS:
141: Dbl_increment(resultp1,resultp2);
142: break;
143: case ROUNDNEAREST:
144: /* stickybit is always true, so guardbit
145: * is enough to determine rounding */
146: if (guardbit) {
147: Dbl_increment(resultp1,resultp2);
148: }
149: break;
150: }
151: /* increment result exponent by 1 if mantissa overflowed */
152: if (Dbl_isone_hiddenoverflow(resultp1)) src_exponent+=2;
153:
154: if (Is_inexacttrap_enabled()) {
155: Dbl_set_exponent(resultp1,
156: ((src_exponent-DBL_BIAS)>>1)+DBL_BIAS);
157: Dbl_copytoptr(resultp1,resultp2,dstptr);
158: return(INEXACTEXCEPTION);
159: }
160: else Set_inexactflag();
161: }
162: else {
163: Dbl_rightshiftby1(resultp1,resultp2);
164: }
165: Dbl_set_exponent(resultp1,((src_exponent-DBL_BIAS)>>1)+DBL_BIAS);
166: Dbl_copytoptr(resultp1,resultp2,dstptr);
167: return(NOEXCEPTION);
168: }
CVSweb