File: /usr/src/linux/arch/ppc/math-emu/op-common.h
1 /*
2 * BK Id: SCCS/s.op-common.h 1.5 05/17/01 18:14:23 cort
3 */
4
5 #define _FP_DECL(wc, X) \
6 _FP_I_TYPE X##_c, X##_s, X##_e; \
7 _FP_FRAC_DECL_##wc(X)
8
9 /*
10 * Finish truely unpacking a native fp value by classifying the kind
11 * of fp value and normalizing both the exponent and the fraction.
12 */
13
14 #define _FP_UNPACK_CANONICAL(fs, wc, X) \
15 do { \
16 switch (X##_e) \
17 { \
18 default: \
19 _FP_FRAC_HIGH_##wc(X) |= _FP_IMPLBIT_##fs; \
20 _FP_FRAC_SLL_##wc(X, _FP_WORKBITS); \
21 X##_e -= _FP_EXPBIAS_##fs; \
22 X##_c = FP_CLS_NORMAL; \
23 break; \
24 \
25 case 0: \
26 if (_FP_FRAC_ZEROP_##wc(X)) \
27 X##_c = FP_CLS_ZERO; \
28 else \
29 { \
30 /* a denormalized number */ \
31 _FP_I_TYPE _shift; \
32 _FP_FRAC_CLZ_##wc(_shift, X); \
33 _shift -= _FP_FRACXBITS_##fs; \
34 _FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS)); \
35 X##_e -= _FP_EXPBIAS_##fs - 1 + _shift; \
36 X##_c = FP_CLS_NORMAL; \
37 } \
38 break; \
39 \
40 case _FP_EXPMAX_##fs: \
41 if (_FP_FRAC_ZEROP_##wc(X)) \
42 X##_c = FP_CLS_INF; \
43 else \
44 /* we don't differentiate between signaling and quiet nans */ \
45 X##_c = FP_CLS_NAN; \
46 break; \
47 } \
48 } while (0)
49
50
51 /*
52 * Before packing the bits back into the native fp result, take care
53 * of such mundane things as rounding and overflow. Also, for some
54 * kinds of fp values, the original parts may not have been fully
55 * extracted -- but that is ok, we can regenerate them now.
56 */
57
58 #define _FP_PACK_CANONICAL(fs, wc, X) \
59 ({int __ret = 0; \
60 switch (X##_c) \
61 { \
62 case FP_CLS_NORMAL: \
63 X##_e += _FP_EXPBIAS_##fs; \
64 if (X##_e > 0) \
65 { \
66 __ret |= _FP_ROUND(wc, X); \
67 if (_FP_FRAC_OVERP_##wc(fs, X)) \
68 { \
69 _FP_FRAC_SRL_##wc(X, (_FP_WORKBITS+1)); \
70 X##_e++; \
71 } \
72 else \
73 _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
74 if (X##_e >= _FP_EXPMAX_##fs) \
75 { \
76 /* overflow to infinity */ \
77 X##_e = _FP_EXPMAX_##fs; \
78 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
79 __ret |= EFLAG_OVERFLOW; \
80 } \
81 } \
82 else \
83 { \
84 /* we've got a denormalized number */ \
85 X##_e = -X##_e + 1; \
86 if (X##_e <= _FP_WFRACBITS_##fs) \
87 { \
88 _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs); \
89 __ret |= _FP_ROUND(wc, X); \
90 _FP_FRAC_SLL_##wc(X, 1); \
91 if (_FP_FRAC_OVERP_##wc(fs, X)) \
92 { \
93 X##_e = 1; \
94 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
95 } \
96 else \
97 { \
98 X##_e = 0; \
99 _FP_FRAC_SRL_##wc(X, _FP_WORKBITS+1); \
100 __ret |= EFLAG_UNDERFLOW; \
101 } \
102 } \
103 else \
104 { \
105 /* underflow to zero */ \
106 X##_e = 0; \
107 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
108 __ret |= EFLAG_UNDERFLOW; \
109 } \
110 } \
111 break; \
112 \
113 case FP_CLS_ZERO: \
114 X##_e = 0; \
115 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
116 break; \
117 \
118 case FP_CLS_INF: \
119 X##_e = _FP_EXPMAX_##fs; \
120 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
121 break; \
122 \
123 case FP_CLS_NAN: \
124 X##_e = _FP_EXPMAX_##fs; \
125 if (!_FP_KEEPNANFRACP) \
126 { \
127 _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \
128 X##_s = 0; \
129 } \
130 else \
131 _FP_FRAC_HIGH_##wc(X) |= _FP_QNANBIT_##fs; \
132 break; \
133 } \
134 __ret; \
135 })
136
137
138 /*
139 * Main addition routine. The input values should be cooked.
140 */
141
142 #define _FP_ADD(fs, wc, R, X, Y) \
143 do { \
144 switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \
145 { \
146 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \
147 { \
148 /* shift the smaller number so that its exponent matches the larger */ \
149 _FP_I_TYPE diff = X##_e - Y##_e; \
150 \
151 if (diff < 0) \
152 { \
153 diff = -diff; \
154 if (diff <= _FP_WFRACBITS_##fs) \
155 _FP_FRAC_SRS_##wc(X, diff, _FP_WFRACBITS_##fs); \
156 else if (!_FP_FRAC_ZEROP_##wc(X)) \
157 _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \
158 else \
159 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
160 R##_e = Y##_e; \
161 } \
162 else \
163 { \
164 if (diff > 0) \
165 { \
166 if (diff <= _FP_WFRACBITS_##fs) \
167 _FP_FRAC_SRS_##wc(Y, diff, _FP_WFRACBITS_##fs); \
168 else if (!_FP_FRAC_ZEROP_##wc(Y)) \
169 _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \
170 else \
171 _FP_FRAC_SET_##wc(Y, _FP_ZEROFRAC_##wc); \
172 } \
173 R##_e = X##_e; \
174 } \
175 \
176 R##_c = FP_CLS_NORMAL; \
177 \
178 if (X##_s == Y##_s) \
179 { \
180 R##_s = X##_s; \
181 _FP_FRAC_ADD_##wc(R, X, Y); \
182 if (_FP_FRAC_OVERP_##wc(fs, R)) \
183 { \
184 _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \
185 R##_e++; \
186 } \
187 } \
188 else \
189 { \
190 R##_s = X##_s; \
191 _FP_FRAC_SUB_##wc(R, X, Y); \
192 if (_FP_FRAC_ZEROP_##wc(R)) \
193 { \
194 /* return an exact zero */ \
195 if (FP_ROUNDMODE == FP_RND_MINF) \
196 R##_s |= Y##_s; \
197 else \
198 R##_s &= Y##_s; \
199 R##_c = FP_CLS_ZERO; \
200 } \
201 else \
202 { \
203 if (_FP_FRAC_NEGP_##wc(R)) \
204 { \
205 _FP_FRAC_SUB_##wc(R, Y, X); \
206 R##_s = Y##_s; \
207 } \
208 \
209 /* renormalize after subtraction */ \
210 _FP_FRAC_CLZ_##wc(diff, R); \
211 diff -= _FP_WFRACXBITS_##fs; \
212 if (diff) \
213 { \
214 R##_e -= diff; \
215 _FP_FRAC_SLL_##wc(R, diff); \
216 } \
217 } \
218 } \
219 break; \
220 } \
221 \
222 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \
223 _FP_CHOOSENAN(fs, wc, R, X, Y); \
224 break; \
225 \
226 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \
227 R##_e = X##_e; \
228 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \
229 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \
230 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \
231 _FP_FRAC_COPY_##wc(R, X); \
232 R##_s = X##_s; \
233 R##_c = X##_c; \
234 break; \
235 \
236 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \
237 R##_e = Y##_e; \
238 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \
239 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \
240 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \
241 _FP_FRAC_COPY_##wc(R, Y); \
242 R##_s = Y##_s; \
243 R##_c = Y##_c; \
244 break; \
245 \
246 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \
247 if (X##_s != Y##_s) \
248 { \
249 /* +INF + -INF => NAN */ \
250 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
251 R##_s = X##_s ^ Y##_s; \
252 R##_c = FP_CLS_NAN; \
253 break; \
254 } \
255 /* FALLTHRU */ \
256 \
257 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \
258 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \
259 R##_s = X##_s; \
260 R##_c = FP_CLS_INF; \
261 break; \
262 \
263 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \
264 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \
265 R##_s = Y##_s; \
266 R##_c = FP_CLS_INF; \
267 break; \
268 \
269 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \
270 /* make sure the sign is correct */ \
271 if (FP_ROUNDMODE == FP_RND_MINF) \
272 R##_s = X##_s | Y##_s; \
273 else \
274 R##_s = X##_s & Y##_s; \
275 R##_c = FP_CLS_ZERO; \
276 break; \
277 \
278 default: \
279 abort(); \
280 } \
281 } while (0)
282
283
284 /*
285 * Main negation routine. FIXME -- when we care about setting exception
286 * bits reliably, this will not do. We should examine all of the fp classes.
287 */
288
289 #define _FP_NEG(fs, wc, R, X) \
290 do { \
291 _FP_FRAC_COPY_##wc(R, X); \
292 R##_c = X##_c; \
293 R##_e = X##_e; \
294 R##_s = 1 ^ X##_s; \
295 } while (0)
296
297
298 /*
299 * Main multiplication routine. The input values should be cooked.
300 */
301
302 #define _FP_MUL(fs, wc, R, X, Y) \
303 do { \
304 R##_s = X##_s ^ Y##_s; \
305 switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \
306 { \
307 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \
308 R##_c = FP_CLS_NORMAL; \
309 R##_e = X##_e + Y##_e + 1; \
310 \
311 _FP_MUL_MEAT_##fs(R,X,Y); \
312 \
313 if (_FP_FRAC_OVERP_##wc(fs, R)) \
314 _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \
315 else \
316 R##_e--; \
317 break; \
318 \
319 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \
320 _FP_CHOOSENAN(fs, wc, R, X, Y); \
321 break; \
322 \
323 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \
324 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \
325 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \
326 R##_s = X##_s; \
327 \
328 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \
329 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \
330 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \
331 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \
332 _FP_FRAC_COPY_##wc(R, X); \
333 R##_c = X##_c; \
334 break; \
335 \
336 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \
337 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \
338 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \
339 R##_s = Y##_s; \
340 \
341 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \
342 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \
343 _FP_FRAC_COPY_##wc(R, Y); \
344 R##_c = Y##_c; \
345 break; \
346 \
347 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \
348 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \
349 R##_c = FP_CLS_NAN; \
350 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
351 break; \
352 \
353 default: \
354 abort(); \
355 } \
356 } while (0)
357
358
359 /*
360 * Main division routine. The input values should be cooked.
361 */
362
363 #define _FP_DIV(fs, wc, R, X, Y) \
364 do { \
365 R##_s = X##_s ^ Y##_s; \
366 switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \
367 { \
368 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \
369 R##_c = FP_CLS_NORMAL; \
370 R##_e = X##_e - Y##_e; \
371 \
372 _FP_DIV_MEAT_##fs(R,X,Y); \
373 break; \
374 \
375 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \
376 _FP_CHOOSENAN(fs, wc, R, X, Y); \
377 break; \
378 \
379 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \
380 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \
381 case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \
382 R##_s = X##_s; \
383 _FP_FRAC_COPY_##wc(R, X); \
384 R##_c = X##_c; \
385 break; \
386 \
387 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \
388 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \
389 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \
390 R##_s = Y##_s; \
391 _FP_FRAC_COPY_##wc(R, Y); \
392 R##_c = Y##_c; \
393 break; \
394 \
395 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \
396 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \
397 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \
398 R##_c = FP_CLS_ZERO; \
399 break; \
400 \
401 case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \
402 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \
403 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \
404 R##_c = FP_CLS_INF; \
405 break; \
406 \
407 case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \
408 case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \
409 R##_c = FP_CLS_NAN; \
410 _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
411 break; \
412 \
413 default: \
414 abort(); \
415 } \
416 } while (0)
417
418
419 /*
420 * Main differential comparison routine. The inputs should be raw not
421 * cooked. The return is -1,0,1 for normal values, 2 otherwise.
422 */
423
424 #define _FP_CMP(fs, wc, ret, X, Y, un) \
425 do { \
426 /* NANs are unordered */ \
427 if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \
428 || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \
429 { \
430 ret = un; \
431 } \
432 else \
433 { \
434 int __x_zero = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0; \
435 int __y_zero = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0; \
436 \
437 if (__x_zero && __y_zero) \
438 ret = 0; \
439 else if (__x_zero) \
440 ret = Y##_s ? 1 : -1; \
441 else if (__y_zero) \
442 ret = X##_s ? -1 : 1; \
443 else if (X##_s != Y##_s) \
444 ret = X##_s ? -1 : 1; \
445 else if (X##_e > Y##_e) \
446 ret = X##_s ? -1 : 1; \
447 else if (X##_e < Y##_e) \
448 ret = X##_s ? 1 : -1; \
449 else if (_FP_FRAC_GT_##wc(X, Y)) \
450 ret = X##_s ? -1 : 1; \
451 else if (_FP_FRAC_GT_##wc(Y, X)) \
452 ret = X##_s ? 1 : -1; \
453 else \
454 ret = 0; \
455 } \
456 } while (0)
457
458
459 /* Simplification for strict equality. */
460
461 #define _FP_CMP_EQ(fs, wc, ret, X, Y) \
462 do { \
463 /* NANs are unordered */ \
464 if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \
465 || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \
466 { \
467 ret = 1; \
468 } \
469 else \
470 { \
471 ret = !(X##_e == Y##_e \
472 && _FP_FRAC_EQ_##wc(X, Y) \
473 && (X##_s == Y##_s || !X##_e && _FP_FRAC_ZEROP_##wc(X))); \
474 } \
475 } while (0)
476
477 /*
478 * Main square root routine. The input value should be cooked.
479 */
480
481 #define _FP_SQRT(fs, wc, R, X) \
482 do { \
483 _FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S); \
484 _FP_W_TYPE q; \
485 switch (X##_c) \
486 { \
487 case FP_CLS_NAN: \
488 R##_s = 0; \
489 R##_c = FP_CLS_NAN; \
490 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
491 break; \
492 case FP_CLS_INF: \
493 if (X##_s) \
494 { \
495 R##_s = 0; \
496 R##_c = FP_CLS_NAN; /* sNAN */ \
497 } \
498 else \
499 { \
500 R##_s = 0; \
501 R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */ \
502 } \
503 break; \
504 case FP_CLS_ZERO: \
505 R##_s = X##_s; \
506 R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */ \
507 break; \
508 case FP_CLS_NORMAL: \
509 R##_s = 0; \
510 if (X##_s) \
511 { \
512 R##_c = FP_CLS_NAN; /* sNAN */ \
513 break; \
514 } \
515 R##_c = FP_CLS_NORMAL; \
516 if (X##_e & 1) \
517 _FP_FRAC_SLL_##wc(X, 1); \
518 R##_e = X##_e >> 1; \
519 _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc); \
520 _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc); \
521 q = _FP_OVERFLOW_##fs; \
522 _FP_FRAC_SLL_##wc(X, 1); \
523 _FP_SQRT_MEAT_##wc(R, S, T, X, q); \
524 _FP_FRAC_SRL_##wc(R, 1); \
525 } \
526 } while (0)
527
528 /*
529 * Convert from FP to integer
530 */
531
532 /* "When a NaN, infinity, large positive argument >= 2147483648.0, or
533 * large negative argument <= -2147483649.0 is converted to an integer,
534 * the invalid_current bit...should be set and fp_exception_IEEE_754 should
535 * be raised. If the floating point invalid trap is disabled, no trap occurs
536 * and a numerical result is generated: if the sign bit of the operand
537 * is 0, the result is 2147483647; if the sign bit of the operand is 1,
538 * the result is -2147483648."
539 * Similarly for conversion to extended ints, except that the boundaries
540 * are >= 2^63, <= -(2^63 + 1), and the results are 2^63 + 1 for s=0 and
541 * -2^63 for s=1.
542 * -- SPARC Architecture Manual V9, Appendix B, which specifies how
543 * SPARCs resolve implementation dependencies in the IEEE-754 spec.
544 * I don't believe that the code below follows this. I'm not even sure
545 * it's right!
546 * It doesn't cope with needing to convert to an n bit integer when there
547 * is no n bit integer type. Fortunately gcc provides long long so this
548 * isn't a problem for sparc32.
549 * I have, however, fixed its NaN handling to conform as above.
550 * -- PMM 02/1998
551 * NB: rsigned is not 'is r declared signed?' but 'should the value stored
552 * in r be signed or unsigned?'. r is always(?) declared unsigned.
553 * Comments below are mine, BTW -- PMM
554 */
555 #define _FP_TO_INT(fs, wc, r, X, rsize, rsigned) \
556 do { \
557 switch (X##_c) \
558 { \
559 case FP_CLS_NORMAL: \
560 if (X##_e < 0) \
561 { \
562 /* case FP_CLS_NAN: see above! */ \
563 case FP_CLS_ZERO: \
564 r = 0; \
565 } \
566 else if (X##_e >= rsize - (rsigned != 0)) \
567 { /* overflow */ \
568 case FP_CLS_NAN: \
569 case FP_CLS_INF: \
570 if (rsigned) \
571 { \
572 r = 1; \
573 r <<= rsize - 1; \
574 r -= 1 - X##_s; \
575 } \
576 else \
577 { \
578 r = 0; \
579 if (!X##_s) \
580 r = ~r; \
581 } \
582 } \
583 else \
584 { \
585 if (_FP_W_TYPE_SIZE*wc < rsize) \
586 { \
587 _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
588 r <<= X##_e - _FP_WFRACBITS_##fs; \
589 } \
590 else \
591 { \
592 if (X##_e >= _FP_WFRACBITS_##fs) \
593 _FP_FRAC_SLL_##wc(X, (X##_e - _FP_WFRACBITS_##fs + 1));\
594 else \
595 _FP_FRAC_SRL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1));\
596 _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
597 } \
598 if (rsigned && X##_s) \
599 r = -r; \
600 } \
601 break; \
602 } \
603 } while (0)
604
605 #define _FP_FROM_INT(fs, wc, X, r, rsize, rtype) \
606 do { \
607 if (r) \
608 { \
609 X##_c = FP_CLS_NORMAL; \
610 \
611 if ((X##_s = (r < 0))) \
612 r = -r; \
613 /* Note that `r' is now considered unsigned, so we don't have \
614 to worry about the single signed overflow case. */ \
615 \
616 if (rsize <= _FP_W_TYPE_SIZE) \
617 __FP_CLZ(X##_e, r); \
618 else \
619 __FP_CLZ_2(X##_e, (_FP_W_TYPE)(r >> _FP_W_TYPE_SIZE), \
620 (_FP_W_TYPE)r); \
621 if (rsize < _FP_W_TYPE_SIZE) \
622 X##_e -= (_FP_W_TYPE_SIZE - rsize); \
623 X##_e = rsize - X##_e - 1; \
624 \
625 if (_FP_FRACBITS_##fs < rsize && _FP_WFRACBITS_##fs < X##_e) \
626 __FP_FRAC_SRS_1(r, (X##_e - _FP_WFRACBITS_##fs), rsize); \
627 r &= ~((_FP_W_TYPE)1 << X##_e); \
628 _FP_FRAC_DISASSEMBLE_##wc(X, ((unsigned rtype)r), rsize); \
629 _FP_FRAC_SLL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1)); \
630 } \
631 else \
632 { \
633 X##_c = FP_CLS_ZERO, X##_s = 0; \
634 } \
635 } while (0)
636
637
638 #define FP_CONV(dfs,sfs,dwc,swc,D,S) \
639 do { \
640 _FP_FRAC_CONV_##dwc##_##swc(dfs, sfs, D, S); \
641 D##_e = S##_e; \
642 D##_c = S##_c; \
643 D##_s = S##_s; \
644 } while (0)
645
646 /*
647 * Helper primitives.
648 */
649
650 /* Count leading zeros in a word. */
651
652 #ifndef __FP_CLZ
653 #if _FP_W_TYPE_SIZE < 64
654 /* this is just to shut the compiler up about shifts > word length -- PMM 02/1998 */
655 #define __FP_CLZ(r, x) \
656 do { \
657 _FP_W_TYPE _t = (x); \
658 r = _FP_W_TYPE_SIZE - 1; \
659 if (_t > 0xffff) r -= 16; \
660 if (_t > 0xffff) _t >>= 16; \
661 if (_t > 0xff) r -= 8; \
662 if (_t > 0xff) _t >>= 8; \
663 if (_t & 0xf0) r -= 4; \
664 if (_t & 0xf0) _t >>= 4; \
665 if (_t & 0xc) r -= 2; \
666 if (_t & 0xc) _t >>= 2; \
667 if (_t & 0x2) r -= 1; \
668 } while (0)
669 #else /* not _FP_W_TYPE_SIZE < 64 */
670 #define __FP_CLZ(r, x) \
671 do { \
672 _FP_W_TYPE _t = (x); \
673 r = _FP_W_TYPE_SIZE - 1; \
674 if (_t > 0xffffffff) r -= 32; \
675 if (_t > 0xffffffff) _t >>= 32; \
676 if (_t > 0xffff) r -= 16; \
677 if (_t > 0xffff) _t >>= 16; \
678 if (_t > 0xff) r -= 8; \
679 if (_t > 0xff) _t >>= 8; \
680 if (_t & 0xf0) r -= 4; \
681 if (_t & 0xf0) _t >>= 4; \
682 if (_t & 0xc) r -= 2; \
683 if (_t & 0xc) _t >>= 2; \
684 if (_t & 0x2) r -= 1; \
685 } while (0)
686 #endif /* not _FP_W_TYPE_SIZE < 64 */
687 #endif /* ndef __FP_CLZ */
688
689 #define _FP_DIV_HELP_imm(q, r, n, d) \
690 do { \
691 q = n / d, r = n % d; \
692 } while (0)
693
694