4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
22 #pragma ident "%Z%%M% %I% %E% SMI"
25 * Copyright (c) 1988 by Sun Microsystems, Inc.
29 #include "_Qglobals.h"
33 unpacked
*px
, *py
, *pz
;
40 pz
->sign
= px
->sign
^ py
->sign
;
42 if ((py
->fpclass
== fp_quiet
) || (py
->fpclass
== fp_signaling
)) {
46 switch (px
->fpclass
) {
52 if (px
->fpclass
== py
->fpclass
) { /* 0/0 or inf/inf */
54 pz
->fpclass
= fp_quiet
;
58 switch (py
->fpclass
) {
59 case fp_zero
: /* number/0 */
60 fpu_set_exception(fp_division
);
61 pz
->fpclass
= fp_infinity
;
63 case fp_infinity
: /* number/inf */
64 pz
->fpclass
= fp_zero
;
69 /* Now x and y are both normal or subnormal. */
71 r
[0] = px
->significand
[0];
72 r
[1] = px
->significand
[1];
73 r
[2] = px
->significand
[2];
74 r
[3] = px
->significand
[3];
77 if(fpu_cmpli(r
,y
,4)>=0)
78 pz
->exponent
= px
->exponent
- py
->exponent
;
80 pz
->exponent
= px
->exponent
- py
->exponent
- 1;
83 while(q
<0x10000) { /* generate quo[0] */
85 if(fpu_cmpli(r
,y
,4)>=0) {
86 q
+= 1; /* if r>y do r-=y and q+=1 */
88 c
= fpu_sub3wc(&r
[3],r
[3],y
[3],c
);
89 c
= fpu_sub3wc(&r
[2],r
[2],y
[2],c
);
90 c
= fpu_sub3wc(&r
[1],r
[1],y
[1],c
);
91 c
= fpu_sub3wc(&r
[0],r
[0],y
[0],c
);
93 r
[0] = (r
[0]<<1)|((r
[1]&0x80000000)>>31); /* r << 1 */
94 r
[1] = (r
[1]<<1)|((r
[2]&0x80000000)>>31);
95 r
[2] = (r
[2]<<1)|((r
[3]&0x80000000)>>31);
99 q
=0; /* generate quo[1] */
103 if(fpu_cmpli(r
,y
,4)>=0) {
104 q
+= 1; /* if r>y do r-=y and q+=1 */
106 c
= fpu_sub3wc(&r
[3],r
[3],y
[3],c
);
107 c
= fpu_sub3wc(&r
[2],r
[2],y
[2],c
);
108 c
= fpu_sub3wc(&r
[1],r
[1],y
[1],c
);
109 c
= fpu_sub3wc(&r
[0],r
[0],y
[0],c
);
111 r
[0] = (r
[0]<<1)|((r
[1]&0x80000000)>>31); /* r << 1 */
112 r
[1] = (r
[1]<<1)|((r
[2]&0x80000000)>>31);
113 r
[2] = (r
[2]<<1)|((r
[3]&0x80000000)>>31);
116 pz
->significand
[1] = q
;
117 q
=0; /* generate quo[2] */
121 if(fpu_cmpli(r
,y
,4)>=0) {
122 q
+= 1; /* if r>y do r-=y and q+=1 */
124 c
= fpu_sub3wc(&r
[3],r
[3],y
[3],c
);
125 c
= fpu_sub3wc(&r
[2],r
[2],y
[2],c
);
126 c
= fpu_sub3wc(&r
[1],r
[1],y
[1],c
);
127 c
= fpu_sub3wc(&r
[0],r
[0],y
[0],c
);
129 r
[0] = (r
[0]<<1)|((r
[1]&0x80000000)>>31); /* r << 1 */
130 r
[1] = (r
[1]<<1)|((r
[2]&0x80000000)>>31);
131 r
[2] = (r
[2]<<1)|((r
[3]&0x80000000)>>31);
134 pz
->significand
[2] = q
;
135 q
=0; /* generate quo[3] */
139 if(fpu_cmpli(r
,y
,4)>=0) {
140 q
+= 1; /* if r>y do r-=y and q+=1 */
142 c
= fpu_sub3wc(&r
[3],r
[3],y
[3],c
);
143 c
= fpu_sub3wc(&r
[2],r
[2],y
[2],c
);
144 c
= fpu_sub3wc(&r
[1],r
[1],y
[1],c
);
145 c
= fpu_sub3wc(&r
[0],r
[0],y
[0],c
);
147 r
[0] = (r
[0]<<1)|((r
[1]&0x80000000)>>31); /* r << 1 */
148 r
[1] = (r
[1]<<1)|((r
[2]&0x80000000)>>31);
149 r
[2] = (r
[2]<<1)|((r
[3]&0x80000000)>>31);
152 pz
->significand
[3] = q
;
153 if((r
[0]|r
[1]|r
[2]|r
[3])==0) pz
->sticky
= pz
->rounded
= 0;
155 pz
->sticky
= 1; /* half way case won't occur */
156 if(fpu_cmpli(r
,y
,4)>=0) pz
->rounded
= 1;
164 { /* *pz gets sqrt(*px) */
166 unsigned *x
,r
,c
,q
,t
[4],s
[4];
168 switch (px
->fpclass
) {
174 if (px
->sign
== 1) { /* sqrt(-inf) */
176 pz
->fpclass
= fp_quiet
;
180 if (px
->sign
== 1) { /* sqrt(-norm) */
182 pz
->fpclass
= fp_quiet
;
187 /* Now x is normal. */
189 if (px
->exponent
& 1) { /* sqrt(1.f * 2**odd) = sqrt (2.+2f) *
191 pz
->exponent
= (px
->exponent
- 1) / 2;
192 x
[0] = (x
[0]<<1)|((x
[1]&0x80000000)>>31); /* x<<1 */
193 x
[1] = (x
[1]<<1)|((x
[2]&0x80000000)>>31);
194 x
[2] = (x
[2]<<1)|((x
[3]&0x80000000)>>31);
196 } else { /* sqrt(1.f * 2**even) = sqrt (1.f) *
198 pz
->exponent
= px
->exponent
/ 2;
200 s
[0]=s
[1]=s
[2]=s
[3]=t
[0]=t
[1]=t
[2]=t
[3]=0;
203 while(r
!=0) { /* compute sqrt[0] */
210 x
[0] = (x
[0]<<1)|((x
[1]&0x80000000)>>31); /* x<<1 */
211 x
[1] = (x
[1]<<1)|((x
[2]&0x80000000)>>31);
212 x
[2] = (x
[2]<<1)|((x
[3]&0x80000000)>>31);
216 pz
->significand
[0] = q
;
219 while(r
!=0) { /* compute sqrt[1] */
220 t
[1] = s
[1]+r
; /* no carry */
222 if(fpu_cmpli(t
,x
,2)<=0) {
224 c
= fpu_add3wc(&s
[1],t
[1],r
,c
);
225 c
= fpu_add3wc(&s
[0],t
[0],0,c
);
227 c
= fpu_sub3wc(&x
[1],x
[1],t
[1],c
);
228 c
= fpu_sub3wc(&x
[0],x
[0],t
[0],c
);
231 x
[0] = (x
[0]<<1)|((x
[1]&0x80000000)>>31); /* x<<1 */
232 x
[1] = (x
[1]<<1)|((x
[2]&0x80000000)>>31);
233 x
[2] = (x
[2]<<1)|((x
[3]&0x80000000)>>31);
237 pz
->significand
[1] = q
;
240 while(r
!=0) { /* compute sqrt[2] */
241 t
[2] = s
[2]+r
; /* no carry */
244 if(fpu_cmpli(t
,x
,3)<=0) {
246 c
= fpu_add3wc(&s
[2],t
[2],r
,c
);
247 c
= fpu_add3wc(&s
[1],t
[1],0,c
);
248 c
= fpu_add3wc(&s
[0],t
[0],0,c
);
250 c
= fpu_sub3wc(&x
[2],x
[2],t
[2],c
);
251 c
= fpu_sub3wc(&x
[1],x
[1],t
[1],c
);
252 c
= fpu_sub3wc(&x
[0],x
[0],t
[0],c
);
255 x
[0] = (x
[0]<<1)|((x
[1]&0x80000000)>>31); /* x<<1 */
256 x
[1] = (x
[1]<<1)|((x
[2]&0x80000000)>>31);
257 x
[2] = (x
[2]<<1)|((x
[3]&0x80000000)>>31);
261 pz
->significand
[2] = q
;
264 while(r
!=0) { /* compute sqrt[3] */
265 t
[3] = s
[3]+r
; /* no carry */
269 if(fpu_cmpli(t
,x
,4)<=0) {
271 c
= fpu_add3wc(&s
[3],t
[3],r
,c
);
272 c
= fpu_add3wc(&s
[2],t
[2],0,c
);
273 c
= fpu_add3wc(&s
[1],t
[1],0,c
);
274 c
= fpu_add3wc(&s
[0],t
[0],0,c
);
276 c
= fpu_sub3wc(&x
[3],x
[3],t
[3],c
);
277 c
= fpu_sub3wc(&x
[2],x
[2],t
[2],c
);
278 c
= fpu_sub3wc(&x
[1],x
[1],t
[1],c
);
279 c
= fpu_sub3wc(&x
[0],x
[0],t
[0],c
);
282 x
[0] = (x
[0]<<1)|((x
[1]&0x80000000)>>31); /* x<<1 */
283 x
[1] = (x
[1]<<1)|((x
[2]&0x80000000)>>31);
284 x
[2] = (x
[2]<<1)|((x
[3]&0x80000000)>>31);
288 pz
->significand
[3] = q
;
289 if((x
[0]|x
[1]|x
[2]|x
[3])==0) {
290 pz
->sticky
= pz
->rounded
= 0;
293 if(fpu_cmpli(s
,x
,4)<0) pz
->rounded
=1; else pz
->rounded
= 0;