8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / libbc / libc / gen / common / _Qfaddsub.c
blobc9bc64f49e9f69e1e172319a802922831d76c432
1 /*
2 * CDDL HEADER START
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
7 * with the License.
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]
20 * CDDL HEADER END
22 #pragma ident "%Z%%M% %I% %E% SMI"
25 * Copyright (c) 1988 by Sun Microsystems, Inc.
28 #include "_Qquad.h"
29 #include "_Qglobals.h"
31 PRIVATE void
32 true_add(px, py, pz)
33 unpacked *px, *py, *pz;
36 unsigned c;
37 unpacked *pt;
39 if ((int) px->fpclass < (int) py->fpclass) { /* Reverse. */
40 pt = py;
41 py = px;
42 px = pt;
44 /* Now class(x) >= class(y). */
45 switch (px->fpclass) {
46 case fp_quiet: /* NaN + x -> NaN */
47 case fp_signaling: /* NaN + x -> NaN */
48 case fp_infinity: /* Inf + x -> Inf */
49 case fp_zero: /* 0 + 0 -> 0 */
50 *pz = *px;
51 return;
52 default:
53 if (py->fpclass == fp_zero) {
54 *pz = *px;
55 return;
58 /* Now z is normal or subnormal. */
59 /* Now y is normal or subnormal. */
60 if (px->exponent < py->exponent) { /* Reverse. */
61 pt = py;
62 py = px;
63 px = pt;
65 /* Now class(x) >= class(y). */
66 pz->fpclass = px->fpclass;
67 pz->sign = px->sign;
68 pz->exponent = px->exponent;
69 pz->rounded = pz->sticky = 0;
71 if (px->exponent != py->exponent) { /* pre-alignment required */
72 fpu_rightshift(py, pz->exponent - py->exponent);
73 pz->rounded = py->rounded;
74 pz->sticky = py->sticky;
76 c = 0;
77 c = fpu_add3wc(&(pz->significand[3]),px->significand[3],
78 py->significand[3],c);
79 c = fpu_add3wc(&(pz->significand[2]),px->significand[2],
80 py->significand[2],c);
81 c = fpu_add3wc(&(pz->significand[1]),px->significand[1],
82 py->significand[1],c);
83 c = fpu_add3wc(&(pz->significand[0]),px->significand[0],
84 py->significand[0],c);
86 /* Handle carry out of msb. */
87 if(pz->significand[0]>=0x20000) {
88 fpu_rightshift(pz, 1); /* Carried out bit. */
89 pz->exponent ++; /* Renormalize. */
91 return;
94 PRIVATE void
95 true_sub(px, py, pz)
96 unpacked *px, *py, *pz;
99 unsigned *z,g,s,r,c;
100 int n;
101 unpacked *pt;
103 if ((int) px->fpclass < (int) py->fpclass) { /* Reverse. */
104 pt = py;
105 py = px;
106 px = pt;
108 /* Now class(x) >= class(y). */
109 *pz = *px; /* Tentative difference: x. */
110 switch (pz->fpclass) {
111 case fp_quiet: /* NaN - x -> NaN */
112 case fp_signaling: /* NaN - x -> NaN */
113 return;
114 case fp_infinity: /* Inf - x -> Inf */
115 if (py->fpclass == fp_infinity) {
116 fpu_error_nan(pz); /* Inf - Inf -> NaN */
117 pz->fpclass = fp_quiet;
119 return;
120 case fp_zero: /* 0 - 0 -> 0 */
121 pz->sign = (fp_direction == fp_negative);
122 return;
123 default:
124 if (py->fpclass == fp_zero)
125 return;
128 /* x and y are both normal or subnormal. */
130 if (px->exponent < py->exponent) { /* Reverse. */
131 pt = py;
132 py = px;
133 px = pt;
135 /* Now exp(x) >= exp(y). */
136 pz->fpclass = px->fpclass;
137 pz->sign = px->sign;
138 pz->exponent = px->exponent;
139 pz->rounded = 0;
140 pz->sticky = 0;
141 z = pz->significand;
143 if (px->exponent == py->exponent) { /* no pre-alignment required */
144 c = 0;
145 c = fpu_sub3wc(&z[3],px->significand[3],py->significand[3],c);
146 c = fpu_sub3wc(&z[2],px->significand[2],py->significand[2],c);
147 c = fpu_sub3wc(&z[1],px->significand[1],py->significand[1],c);
148 c = fpu_sub3wc(&z[0],px->significand[0],py->significand[0],c);
149 if((z[0]|z[1]|z[2]|z[3])==0) { /* exact zero result */
150 pz->sign = (fp_direction == fp_negative);
151 pz->fpclass = fp_zero;
152 return;
154 if(z[0]>=0x20000) { /* sign reversal occurred */
155 pz->sign = py->sign;
156 c = 0;
157 c = fpu_neg2wc(&z[3],z[3],c);
158 c = fpu_neg2wc(&z[2],z[2],c);
159 c = fpu_neg2wc(&z[1],z[1],c);
160 c = fpu_neg2wc(&z[0],z[0],c);
162 fpu_normalize(pz);
163 return;
164 } else { /* pre-alignment required */
165 fpu_rightshift(py, pz->exponent - py->exponent - 1);
166 r = py->rounded; /* rounded bit */
167 s = py->sticky; /* sticky bit */
168 fpu_rightshift(py, 1);
169 g = py->rounded; /* guard bit */
170 if(s!=0) r = (r==0);
171 if((r|s)!=0) g = (g==0);/* guard and rounded bits of z */
172 c = ((g|r|s)!=0);
173 c = fpu_sub3wc(&z[3],px->significand[3],py->significand[3],c);
174 c = fpu_sub3wc(&z[2],px->significand[2],py->significand[2],c);
175 c = fpu_sub3wc(&z[1],px->significand[1],py->significand[1],c);
176 c = fpu_sub3wc(&z[0],px->significand[0],py->significand[0],c);
178 if(z[0]>=0x10000) { /* don't need post-shifted */
179 pz->sticky = s|r;
180 pz->rounded = g;
181 } else { /* post-shifted left 1 bit */
182 pz->sticky = s;
183 pz->rounded = r;
184 pz->significand[0] = (z[0]<<1)|((z[1]&0x80000000)>>31);
185 pz->significand[1] = (z[1]<<1)|((z[2]&0x80000000)>>31);
186 pz->significand[2] = (z[2]<<1)|((z[3]&0x80000000)>>31);
187 pz->significand[3] = (z[3]<<1)|g;
188 pz->exponent -= 1;
189 if(z[0]<0x10000) fpu_normalize(pz);
191 return;
195 void
196 _fp_add(px, py, pz)
197 unpacked *px, *py, *pz;
200 if (px->sign == py->sign)
201 true_add(px, py, pz);
202 else
203 true_sub(px, py, pz);
206 void
207 _fp_sub(px, py, pz)
208 unpacked *px, *py, *pz;
211 py->sign = 1 - py->sign;
212 if (px->sign == py->sign)
213 true_add(px, py, pz);
214 else
215 true_sub(px, py, pz);