source: mainline/uspace/softfloat/generic/div.c@ df4ed85

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since df4ed85 was df4ed85, checked in by Jakub Jermar <jakub@…>, 18 years ago

© versus ©

  • Property mode set to 100644
File size: 7.7 KB
Line 
1/*
2 * Copyright (c) 2005 Josef Cejka
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup softfloat
30 * @{
31 */
32/** @file
33 */
34
35#include<sftypes.h>
36#include<add.h>
37#include<div.h>
38#include<comparison.h>
39#include<mul.h>
40#include<common.h>
41
42
43float32 divFloat32(float32 a, float32 b)
44{
45 float32 result;
46 int32_t aexp, bexp, cexp;
47 uint64_t afrac, bfrac, cfrac;
48
49 result.parts.sign = a.parts.sign ^ b.parts.sign;
50
51 if (isFloat32NaN(a)) {
52 if (isFloat32SigNaN(a)) {
53 /*FIXME: SigNaN*/
54 }
55 /*NaN*/
56 return a;
57 }
58
59 if (isFloat32NaN(b)) {
60 if (isFloat32SigNaN(b)) {
61 /*FIXME: SigNaN*/
62 }
63 /*NaN*/
64 return b;
65 }
66
67 if (isFloat32Infinity(a)) {
68 if (isFloat32Infinity(b)) {
69 /*FIXME: inf / inf */
70 result.binary = FLOAT32_NAN;
71 return result;
72 }
73 /* inf / num */
74 result.parts.exp = a.parts.exp;
75 result.parts.fraction = a.parts.fraction;
76 return result;
77 }
78
79 if (isFloat32Infinity(b)) {
80 if (isFloat32Zero(a)) {
81 /* FIXME 0 / inf */
82 result.parts.exp = 0;
83 result.parts.fraction = 0;
84 return result;
85 }
86 /* FIXME: num / inf*/
87 result.parts.exp = 0;
88 result.parts.fraction = 0;
89 return result;
90 }
91
92 if (isFloat32Zero(b)) {
93 if (isFloat32Zero(a)) {
94 /*FIXME: 0 / 0*/
95 result.binary = FLOAT32_NAN;
96 return result;
97 }
98 /* FIXME: division by zero */
99 result.parts.exp = 0;
100 result.parts.fraction = 0;
101 return result;
102 }
103
104
105 afrac = a.parts.fraction;
106 aexp = a.parts.exp;
107 bfrac = b.parts.fraction;
108 bexp = b.parts.exp;
109
110 /* denormalized numbers */
111 if (aexp == 0) {
112 if (afrac == 0) {
113 result.parts.exp = 0;
114 result.parts.fraction = 0;
115 return result;
116 }
117 /* normalize it*/
118
119 afrac <<= 1;
120 /* afrac is nonzero => it must stop */
121 while (! (afrac & FLOAT32_HIDDEN_BIT_MASK) ) {
122 afrac <<= 1;
123 aexp--;
124 }
125 }
126
127 if (bexp == 0) {
128 bfrac <<= 1;
129 /* bfrac is nonzero => it must stop */
130 while (! (bfrac & FLOAT32_HIDDEN_BIT_MASK) ) {
131 bfrac <<= 1;
132 bexp--;
133 }
134 }
135
136 afrac = (afrac | FLOAT32_HIDDEN_BIT_MASK ) << (32 - FLOAT32_FRACTION_SIZE - 1 );
137 bfrac = (bfrac | FLOAT32_HIDDEN_BIT_MASK ) << (32 - FLOAT32_FRACTION_SIZE );
138
139 if ( bfrac <= (afrac << 1) ) {
140 afrac >>= 1;
141 aexp++;
142 }
143
144 cexp = aexp - bexp + FLOAT32_BIAS - 2;
145
146 cfrac = (afrac << 32) / bfrac;
147 if (( cfrac & 0x3F ) == 0) {
148 cfrac |= ( bfrac * cfrac != afrac << 32 );
149 }
150
151 /* pack and round */
152
153 /* find first nonzero digit and shift result and detect possibly underflow */
154 while ((cexp > 0) && (cfrac) && (!(cfrac & (FLOAT32_HIDDEN_BIT_MASK << 7 )))) {
155 cexp--;
156 cfrac <<= 1;
157 /* TODO: fix underflow */
158 };
159
160 cfrac += (0x1 << 6); /* FIXME: 7 is not sure*/
161
162 if (cfrac & (FLOAT32_HIDDEN_BIT_MASK << 7)) {
163 ++cexp;
164 cfrac >>= 1;
165 }
166
167 /* check overflow */
168 if (cexp >= FLOAT32_MAX_EXPONENT ) {
169 /* FIXME: overflow, return infinity */
170 result.parts.exp = FLOAT32_MAX_EXPONENT;
171 result.parts.fraction = 0;
172 return result;
173 }
174
175 if (cexp < 0) {
176 /* FIXME: underflow */
177 result.parts.exp = 0;
178 if ((cexp + FLOAT32_FRACTION_SIZE) < 0) {
179 result.parts.fraction = 0;
180 return result;
181 }
182 cfrac >>= 1;
183 while (cexp < 0) {
184 cexp ++;
185 cfrac >>= 1;
186 }
187
188 } else {
189 result.parts.exp = (uint32_t)cexp;
190 }
191
192 result.parts.fraction = ((cfrac >> 6) & (~FLOAT32_HIDDEN_BIT_MASK));
193
194 return result;
195}
196
197float64 divFloat64(float64 a, float64 b)
198{
199 float64 result;
200 int64_t aexp, bexp, cexp;
201 uint64_t afrac, bfrac, cfrac;
202 uint64_t remlo, remhi;
203
204 result.parts.sign = a.parts.sign ^ b.parts.sign;
205
206 if (isFloat64NaN(a)) {
207
208 if (isFloat64SigNaN(b)) {
209 /*FIXME: SigNaN*/
210 return b;
211 }
212
213 if (isFloat64SigNaN(a)) {
214 /*FIXME: SigNaN*/
215 }
216 /*NaN*/
217 return a;
218 }
219
220 if (isFloat64NaN(b)) {
221 if (isFloat64SigNaN(b)) {
222 /*FIXME: SigNaN*/
223 }
224 /*NaN*/
225 return b;
226 }
227
228 if (isFloat64Infinity(a)) {
229 if (isFloat64Infinity(b) || isFloat64Zero(b)) {
230 /*FIXME: inf / inf */
231 result.binary = FLOAT64_NAN;
232 return result;
233 }
234 /* inf / num */
235 result.parts.exp = a.parts.exp;
236 result.parts.fraction = a.parts.fraction;
237 return result;
238 }
239
240 if (isFloat64Infinity(b)) {
241 if (isFloat64Zero(a)) {
242 /* FIXME 0 / inf */
243 result.parts.exp = 0;
244 result.parts.fraction = 0;
245 return result;
246 }
247 /* FIXME: num / inf*/
248 result.parts.exp = 0;
249 result.parts.fraction = 0;
250 return result;
251 }
252
253 if (isFloat64Zero(b)) {
254 if (isFloat64Zero(a)) {
255 /*FIXME: 0 / 0*/
256 result.binary = FLOAT64_NAN;
257 return result;
258 }
259 /* FIXME: division by zero */
260 result.parts.exp = 0;
261 result.parts.fraction = 0;
262 return result;
263 }
264
265
266 afrac = a.parts.fraction;
267 aexp = a.parts.exp;
268 bfrac = b.parts.fraction;
269 bexp = b.parts.exp;
270
271 /* denormalized numbers */
272 if (aexp == 0) {
273 if (afrac == 0) {
274 result.parts.exp = 0;
275 result.parts.fraction = 0;
276 return result;
277 }
278 /* normalize it*/
279
280 aexp++;
281 /* afrac is nonzero => it must stop */
282 while (! (afrac & FLOAT64_HIDDEN_BIT_MASK) ) {
283 afrac <<= 1;
284 aexp--;
285 }
286 }
287
288 if (bexp == 0) {
289 bexp++;
290 /* bfrac is nonzero => it must stop */
291 while (! (bfrac & FLOAT64_HIDDEN_BIT_MASK) ) {
292 bfrac <<= 1;
293 bexp--;
294 }
295 }
296
297 afrac = (afrac | FLOAT64_HIDDEN_BIT_MASK ) << (64 - FLOAT64_FRACTION_SIZE - 2 );
298 bfrac = (bfrac | FLOAT64_HIDDEN_BIT_MASK ) << (64 - FLOAT64_FRACTION_SIZE - 1);
299
300 if ( bfrac <= (afrac << 1) ) {
301 afrac >>= 1;
302 aexp++;
303 }
304
305 cexp = aexp - bexp + FLOAT64_BIAS - 2;
306
307 cfrac = divFloat64estim(afrac, bfrac);
308
309 if (( cfrac & 0x1FF ) <= 2) { /*FIXME:?? */
310 mul64integers( bfrac, cfrac, &remlo, &remhi);
311 /* (__u128)afrac << 64 - ( ((__u128)remhi<<64) + (__u128)remlo )*/
312 remhi = afrac - remhi - ( remlo > 0);
313 remlo = - remlo;
314
315 while ((int64_t) remhi < 0) {
316 cfrac--;
317 remlo += bfrac;
318 remhi += ( remlo < bfrac );
319 }
320 cfrac |= ( remlo != 0 );
321 }
322
323 /* round and shift */
324 result = finishFloat64(cexp, cfrac, result.parts.sign);
325 return result;
326
327}
328
329uint64_t divFloat64estim(uint64_t a, uint64_t b)
330{
331 uint64_t bhi;
332 uint64_t remhi, remlo;
333 uint64_t result;
334
335 if ( b <= a ) {
336 return 0xFFFFFFFFFFFFFFFFull;
337 }
338
339 bhi = b >> 32;
340 result = ((bhi << 32) <= a) ?( 0xFFFFFFFFull << 32) : ( a / bhi) << 32;
341 mul64integers(b, result, &remlo, &remhi);
342
343 remhi = a - remhi - (remlo > 0);
344 remlo = - remlo;
345
346 b <<= 32;
347 while ( (int64_t) remhi < 0 ) {
348 result -= 0x1ll << 32;
349 remlo += b;
350 remhi += bhi + ( remlo < b );
351 }
352 remhi = (remhi << 32) | (remlo >> 32);
353 if (( bhi << 32) <= remhi) {
354 result |= 0xFFFFFFFF;
355 } else {
356 result |= remhi / bhi;
357 }
358
359
360 return result;
361}
362
363/** @}
364 */
Note: See TracBrowser for help on using the repository browser.