1 /* kf_rem_pio2.c -- float version of k_rem_pio2.c
2 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
3 */
4
5 /*
6 * ====================================================
7 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8 *
9 * Developed at SunPro, a Sun Microsystems, Inc. business.
10 * Permission to use, copy, modify, and distribute this
11 * software is freely granted, provided that this notice
12 * is preserved.
13 * ====================================================
14 */
15
16 #include "fdlibm.h"
17
18 /* In the float version, the input parameter x contains 8 bit
19 integers, not 24 bit integers. 113 bit precision is not supported. */
20
21 static const int init_jk[] = { 4, 7, 9 }; /* initial value for jk */
22
23 static const float PIo2[] = {
24 1.5703125000e+00, /* 0x3fc90000 */
25 4.5776367188e-04, /* 0x39f00000 */
26 2.5987625122e-05, /* 0x37da0000 */
27 7.5437128544e-08, /* 0x33a20000 */
28 6.0026650317e-11, /* 0x2e840000 */
29 7.3896444519e-13, /* 0x2b500000 */
30 5.3845816694e-15, /* 0x27c20000 */
31 5.6378512969e-18, /* 0x22d00000 */
32 8.3009228831e-20, /* 0x1fc40000 */
33 3.2756352257e-22, /* 0x1bc60000 */
34 6.3331015649e-25, /* 0x17440000 */
35 };
36
37 static const float zero = 0.0, one = 1.0,
38 two8 = 2.5600000000e+02, /* 0x43800000 */
39 twon8 = 3.9062500000e-03; /* 0x3b800000 */
40
41 #pragma GCC diagnostic ignored "-Wpragmas"
42 #pragma GCC diagnostic ignored "-Wunknown-warning-option"
43 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
44
45 int
__kernel_rem_pio2f(float * x,float * y,int e0,int nx,int prec,const __int32_t * ipio2)46 __kernel_rem_pio2f(float *x, float *y, int e0, int nx, int prec,
47 const __int32_t *ipio2)
48 {
49 __int32_t jz, jx, jv, jp, jk, carry, n, iq[20], i, j, k, m, q0, ih;
50 float z, fw, f[20], fq[20], q[20];
51
52 /* initialize jk*/
53 jk = init_jk[prec];
54 jp = jk;
55
56 /* determine jx,jv,q0, note that 3>q0 */
57 jx = nx - 1;
58 jv = (e0 - 3) / 8;
59 if (jv < 0)
60 jv = 0;
61 q0 = e0 - 8 * (jv + 1);
62
63 /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */
64 j = jv - jx;
65 m = jx + jk;
66 for (i = 0; i <= m; i++, j++)
67 f[i] = (j < 0) ? zero : (float)ipio2[j];
68
69 /* compute q[0],q[1],...q[jk] */
70 for (i = 0; i <= jk; i++) {
71 for (j = 0, fw = 0.0; j <= jx; j++)
72 fw += x[j] * f[jx + i - j];
73 q[i] = fw;
74 }
75
76 jz = jk;
77 recompute:
78 /* distill q[] into iq[] reversingly */
79 for (i = 0, j = jz, z = q[jz]; j > 0; i++, j--) {
80 fw = (float)((__int32_t)(twon8 * z));
81 iq[i] = (__int32_t)(z - two8 * fw);
82 z = q[j - 1] + fw;
83 }
84
85 /* compute n */
86 z = scalbnf(z, (int)q0); /* actual value of z */
87 z -= (float)8.0 * floorf(z * (float)0.125); /* trim off integer >= 8 */
88 n = (__int32_t)z;
89 z -= (float)n;
90 ih = 0;
91 if (q0 > 0) { /* need iq[jz-1] to determine n */
92 i = (iq[jz - 1] >> (8 - q0));
93 n += i;
94 iq[jz - 1] -= i << (8 - q0);
95 ih = iq[jz - 1] >> (7 - q0);
96 } else if (q0 == 0)
97 ih = iq[jz - 1] >> 7;
98 else if (z >= (float)0.5)
99 ih = 2;
100
101 if (ih > 0) { /* q > 0.5 */
102 n += 1;
103 carry = 0;
104 for (i = 0; i < jz; i++) { /* compute 1-q */
105 j = iq[i];
106 if (carry == 0) {
107 if (j != 0) {
108 carry = 1;
109 iq[i] = 0x100 - j;
110 }
111 } else
112 iq[i] = 0xff - j;
113 }
114 if (q0 > 0) { /* rare case: chance is 1 in 12 */
115 switch (q0) {
116 case 1:
117 iq[jz - 1] &= 0x7f;
118 break;
119 case 2:
120 iq[jz - 1] &= 0x3f;
121 break;
122 }
123 }
124 if (ih == 2) {
125 z = one - z;
126 if (carry != 0)
127 z -= scalbnf(one, (int)q0);
128 }
129 }
130
131 /* check if recomputation is needed */
132 if (z == zero) {
133 j = 0;
134 for (i = jz - 1; i >= jk; i--)
135 j |= iq[i];
136 if (j == 0) { /* need recomputation */
137 for (k = 1; iq[jk - k] == 0; k++)
138 ; /* k = no. of terms needed */
139
140 for (i = jz + 1; i <= jz + k; i++) { /* add q[jz+1] to q[jz+k] */
141 f[jx + i] = (float)ipio2[jv + i];
142 for (j = 0, fw = 0.0; j <= jx; j++)
143 fw += x[j] * f[jx + i - j];
144 q[i] = fw;
145 }
146 jz += k;
147 goto recompute;
148 }
149 }
150
151 /* chop off zero terms */
152 if (z == (float)0.0) {
153 jz -= 1;
154 q0 -= 8;
155 while (iq[jz] == 0) {
156 jz--;
157 q0 -= 8;
158 }
159 } else { /* break z into 8-bit if necessary */
160 z = scalbnf(z, -(int)q0);
161 if (z >= two8) {
162 fw = (float)((__int32_t)(twon8 * z));
163 iq[jz] = (__int32_t)(z - two8 * fw);
164 jz += 1;
165 q0 += 8;
166 iq[jz] = (__int32_t)fw;
167 } else
168 iq[jz] = (__int32_t)z;
169 }
170
171 /* convert integer "bit" chunk to floating-point value */
172 fw = scalbnf(one, (int)q0);
173 for (i = jz; i >= 0; i--) {
174 q[i] = fw * (float)iq[i];
175 fw *= twon8;
176 }
177
178 /* compute PIo2[0,...,jp]*q[jz,...,0] */
179 for (i = jz; i >= 0; i--) {
180 for (fw = 0.0, k = 0; k <= jp && k <= jz - i; k++)
181 fw += PIo2[k] * q[i + k];
182 fq[jz - i] = fw;
183 }
184
185 /* compress fq[] into y[] */
186 switch (prec) {
187 case 0:
188 fw = 0.0;
189 for (i = jz; i >= 0; i--)
190 fw += fq[i];
191 y[0] = (ih == 0) ? fw : -fw;
192 break;
193 case 1:
194 case 2:
195 fw = 0.0;
196 for (i = jz; i >= 0; i--)
197 fw += fq[i];
198 y[0] = (ih == 0) ? fw : -fw;
199 fw = fq[0] - fw;
200 for (i = 1; i <= jz; i++)
201 fw += fq[i];
202 y[1] = (ih == 0) ? fw : -fw;
203 break;
204 case 3: /* painful */
205 for (i = jz; i > 0; i--) {
206 fw = fq[i - 1] + fq[i];
207 fq[i] += fq[i - 1] - fw;
208 fq[i - 1] = fw;
209 }
210 for (i = jz; i > 1; i--) {
211 fw = fq[i - 1] + fq[i];
212 fq[i] += fq[i - 1] - fw;
213 fq[i - 1] = fw;
214 }
215 for (fw = 0.0, i = jz; i >= 2; i--)
216 fw += fq[i];
217 if (ih == 0) {
218 y[0] = fq[0];
219 y[1] = fq[1];
220 y[2] = fw;
221 } else {
222 y[0] = -fq[0];
223 y[1] = -fq[1];
224 y[2] = -fw;
225 }
226 }
227 return n & 7;
228 }
229