becopyheur2: Avoid unnecessary copies of the admissible registers.
[libfirm] / ir / tv / fltcalc.c
1 /*
2  * This file is part of libFirm.
3  * Copyright (C) 2012 University of Karlsruhe.
4  */
5
6 /**
7  * @file
8  * @brief    tarval floating point calculations
9  * @date     2003
10  * @author   Mathias Heil
11  */
12 #include "config.h"
13
14 #include "fltcalc.h"
15 #include "strcalc.h"
16 #include "error.h"
17
18 #include <math.h>
19 #include <inttypes.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <assert.h>
24 #include <stdbool.h>
25
26 #include "xmalloc.h"
27
28 /*
29  * portability stuff (why do we even care about the msvc people with their C89?)
30  */
31
32
33 static long double string_to_long_double(const char *str)
34 {
35 #if __STDC_VERSION__ >= 199901L || _POSIX_C_SOURCE >= 200112L
36         return strtold(str, NULL);
37 #else
38         return strtod(str, NULL);
39 #endif
40 }
41
42 static bool my_isnan(long double val)
43 {
44 #if __STDC_VERSION__ >= 199901L
45         return isnan(val);
46 #else
47         /* hopefully the compiler does not optimize aggressively (=incorrect) */
48         return val != val;
49 #endif
50 }
51
52 static bool my_isinf(long double val)
53 {
54 #if __STDC_VERSION__ >= 199901L
55         return isinf(val);
56 #else
57         /* hopefully the compiler does not optimize aggressively (=incorrect) */
58         return my_isnan(val-val) && !my_isnan(val);
59 #endif
60 }
61
62 /** The number of extra precision rounding bits */
63 #define ROUNDING_BITS 2
64
65 typedef union {
66         struct {
67 #ifdef WORDS_BIGENDIAN
68                 uint32_t high;
69 #else
70                 uint32_t low;
71 #endif
72                 uint32_t mid;
73 #ifdef WORDS_BIGENDIAN
74                 uint32_t low;
75 #else
76                 uint32_t high;
77 #endif
78         } val_ld12;
79         struct {
80 #ifdef WORDS_BIGENDIAN
81                 uint32_t high;
82 #else
83                 uint32_t low;
84 #endif
85 #ifdef WORDS_BIGENDIAN
86                 uint32_t low;
87 #else
88                 uint32_t high;
89 #endif
90         } val_ld8;
91         volatile long double d;
92 } value_t;
93
94 #define CLEAR_BUFFER(buffer) memset(buffer, 0, calc_buffer_size)
95
96 /* our floating point value */
97 struct fp_value {
98         float_descriptor_t desc;
99         unsigned char clss;
100         char sign;
101         char value[1];        /* exp[value_size] + mant[value_size] */
102 };
103
104 #define _exp(a)  &((a)->value[0])
105 #define _mant(a) &((a)->value[value_size])
106
107 #define _save_result(x) memcpy((x), sc_get_buffer(), value_size)
108 #define _shift_right(x, y, res) sc_shr((x), (y), value_size*4, 0, (res))
109 #define _shift_left(x, y, res) sc_shl((x), (y), value_size*4, 0, (res))
110
111 /** A temporary buffer. */
112 static fp_value *calc_buffer = NULL;
113
114 /** Current rounding mode.*/
115 static fc_rounding_mode_t rounding_mode;
116
117 static int calc_buffer_size;
118 static int value_size;
119 static int max_precision;
120
121 /** Exact flag. */
122 static int fc_exact = 1;
123
124 /** pack machine-like */
125 static void *pack(const fp_value *int_float, void *packed)
126 {
127         char     *shift_val;
128         char     *temp;
129         fp_value *val_buffer;
130         int      pos;
131
132         temp      = (char*) alloca(value_size);
133         shift_val = (char*) alloca(value_size);
134
135         switch ((value_class_t)int_float->clss) {
136         case FC_NAN:
137                 val_buffer = (fp_value*) alloca(calc_buffer_size);
138                 fc_get_qnan(&int_float->desc, val_buffer);
139                 int_float = val_buffer;
140                 break;
141
142         case FC_INF:
143                 val_buffer = (fp_value*) alloca(calc_buffer_size);
144                 fc_get_plusinf(&int_float->desc, val_buffer);
145                 val_buffer->sign = int_float->sign;
146                 int_float = val_buffer;
147                 break;
148
149         default:
150                 break;
151         }
152         assert(int_float->desc.explicit_one <= 1);
153
154         /* pack sign: move it to the left after exponent AND mantissa */
155         sc_val_from_ulong(int_float->sign, temp);
156
157         pos = int_float->desc.exponent_size + int_float->desc.mantissa_size + int_float->desc.explicit_one;
158         sc_val_from_ulong(pos, NULL);
159         _shift_left(temp, sc_get_buffer(), packed);
160
161         /* pack exponent: move it to the left after mantissa */
162         pos = int_float->desc.mantissa_size + int_float->desc.explicit_one;
163         sc_val_from_ulong(pos, shift_val);
164         _shift_left(_exp(int_float), shift_val, temp);
165
166         /* combine sign|exponent */
167         sc_or(temp, packed, packed);
168
169         /* extract mantissa */
170         /* remove rounding bits */
171         sc_val_from_ulong(ROUNDING_BITS, shift_val);
172         _shift_right(_mant(int_float), shift_val, temp);
173
174         /* remove leading 1 (or 0 if denormalized) */
175         sc_max_from_bits(pos, 0, shift_val); /* all mantissa bits are 1's */
176         sc_and(temp, shift_val, temp);
177
178         /* combine sign|exponent|mantissa */
179         sc_or(temp, packed, packed);
180
181         return packed;
182 }
183
184 /**
185  * Normalize a fp_value.
186  *
187  * @return non-zero if result is exact
188  */
189 static int normalize(const fp_value *in_val, fp_value *out_val, int sticky)
190 {
191         int exact = 1;
192         int hsb;
193         char lsb, guard, round, round_dir = 0;
194         char *temp = (char*) alloca(value_size);
195
196         /* save rounding bits at the end */
197         hsb = ROUNDING_BITS + in_val->desc.mantissa_size - sc_get_highest_set_bit(_mant(in_val)) - 1;
198
199         if (in_val != out_val)   {
200                 out_val->sign = in_val->sign;
201                 out_val->desc = in_val->desc;
202         }
203
204         out_val->clss = FC_NORMAL;
205
206         /* mantissa all zeros, so zero exponent (because of explicit one) */
207         if (hsb == ROUNDING_BITS + in_val->desc.mantissa_size)   {
208                 sc_val_from_ulong(0, _exp(out_val));
209                 hsb = -1;
210         }
211
212         /* shift the first 1 into the left of the radix point (i.e. hsb == -1) */
213         if (hsb < -1)   {
214                 /* shift right */
215                 sc_val_from_ulong(-hsb-1, temp);
216
217                 _shift_right(_mant(in_val), temp, _mant(out_val));
218
219                 /* remember if some bits were shifted away */
220                 if (sc_had_carry()) {
221                         exact = 0;
222                         sticky = 1;
223                 }
224                 sc_add(_exp(in_val), temp, _exp(out_val));
225         } else if (hsb > -1) {
226                 /* shift left */
227                 sc_val_from_ulong(hsb+1, temp);
228
229                 _shift_left(_mant(in_val), temp, _mant(out_val));
230
231                 sc_sub(_exp(in_val), temp, _exp(out_val));
232         }
233
234         /* check for exponent underflow */
235         if (sc_is_negative(_exp(out_val)) || sc_is_zero(_exp(out_val))) {
236                 /* exponent underflow */
237                 /* shift the mantissa right to have a zero exponent */
238                 sc_val_from_ulong(1, temp);
239                 sc_sub(temp, _exp(out_val), NULL);
240
241                 _shift_right(_mant(out_val), sc_get_buffer(), _mant(out_val));
242                 if (sc_had_carry()) {
243                         exact  = 0;
244                         sticky = 1;
245                 }
246                 /* denormalized means exponent of zero */
247                 sc_val_from_ulong(0, _exp(out_val));
248
249                 out_val->clss = FC_SUBNORMAL;
250         }
251
252         /* perform rounding by adding a value that clears the guard bit and the round bit
253          * and either causes a carry to round up or not */
254         /* get the last 3 bits of the value */
255         lsb = sc_sub_bits(_mant(out_val), out_val->desc.mantissa_size + ROUNDING_BITS, 0) & 0x7;
256         guard = (lsb&0x2)>>1;
257         round = lsb&0x1;
258
259         switch (rounding_mode) {
260         case FC_TONEAREST:
261                 /* round to nearest representable value, if in doubt choose the version
262                  * with lsb == 0 */
263                 round_dir = guard && (sticky || round || lsb>>2);
264                 break;
265         case FC_TOPOSITIVE:
266                 /* if positive: round to one if the exact value is bigger, else to zero */
267                 round_dir = (!out_val->sign && (guard || round || sticky));
268                 break;
269         case FC_TONEGATIVE:
270                 /* if negative: round to one if the exact value is bigger, else to zero */
271                 round_dir = (out_val->sign && (guard || round || sticky));
272                 break;
273         case FC_TOZERO:
274                 /* always round to 0 (chopping mode) */
275                 round_dir = 0;
276                 break;
277         }
278
279         if (round_dir == 1) {
280                 guard = (round^guard)<<1;
281                 lsb = !(round || guard)<<2 | guard | round;
282         } else {
283                 lsb = -((guard<<1) | round);
284         }
285
286         /* add the rounded value */
287         if (lsb != 0) {
288                 sc_val_from_long(lsb, temp);
289                 sc_add(_mant(out_val), temp, _mant(out_val));
290                 exact = 0;
291         }
292
293         /* could have rounded down to zero */
294         if (sc_is_zero(_mant(out_val)) && (out_val->clss == FC_SUBNORMAL))
295                 out_val->clss = FC_ZERO;
296
297         /* check for rounding overflow */
298         hsb = ROUNDING_BITS + out_val->desc.mantissa_size - sc_get_highest_set_bit(_mant(out_val)) - 1;
299         if ((out_val->clss != FC_SUBNORMAL) && (hsb < -1)) {
300                 sc_val_from_ulong(1, temp);
301                 _shift_right(_mant(out_val), temp, _mant(out_val));
302                 if (exact && sc_had_carry())
303                         exact = 0;
304                 sc_add(_exp(out_val), temp, _exp(out_val));
305         } else if ((out_val->clss == FC_SUBNORMAL) && (hsb == -1)) {
306                 /* overflow caused the mantissa to be normal again,
307                  * so adapt the exponent accordingly */
308                 sc_val_from_ulong(1, temp);
309                 sc_add(_exp(out_val), temp, _exp(out_val));
310
311                 out_val->clss = FC_NORMAL;
312         }
313         /* no further rounding is needed, because rounding overflow means
314          * the carry of the original rounding was propagated all the way
315          * up to the bit left of the radix point. This implies the bits
316          * to the right are all zeros (rounding is +1) */
317
318         /* check for exponent overflow */
319         sc_val_from_ulong((1 << out_val->desc.exponent_size) - 1, temp);
320         if (sc_comp(_exp(out_val), temp) != ir_relation_less) {
321                 /* exponent overflow, reaction depends on rounding method:
322                  *
323                  * mode        | sign of value |  result
324                  *--------------------------------------------------------------
325                  * TO_NEAREST  |      +        |   +inf
326                  *             |      -        |   -inf
327                  *--------------------------------------------------------------
328                  * TO_POSITIVE |      +        |   +inf
329                  *             |      -        |   smallest representable value
330                  *--------------------------------------------------------------
331                  * TO_NEAGTIVE |      +        |   largest representable value
332                  *             |      -        |   -inf
333                  *--------------------------------------------------------------
334                  * TO_ZERO     |      +        |   largest representable value
335                  *             |      -        |   smallest representable value
336                  *--------------------------------------------------------------*/
337                 if (out_val->sign == 0) {
338                         /* value is positive */
339                         switch (rounding_mode) {
340                         case FC_TONEAREST:
341                         case FC_TOPOSITIVE:
342                                 out_val->clss = FC_INF;
343                                 break;
344
345                         case FC_TONEGATIVE:
346                         case FC_TOZERO:
347                                 fc_get_max(&out_val->desc, out_val);
348                         }
349                 } else {
350                         /* value is negative */
351                         switch (rounding_mode) {
352                         case FC_TONEAREST:
353                         case FC_TONEGATIVE:
354                                 out_val->clss = FC_INF;
355                                 break;
356
357                         case FC_TOPOSITIVE:
358                         case FC_TOZERO:
359                                 fc_get_min(&out_val->desc, out_val);
360                         }
361                 }
362         }
363         return exact;
364 }
365
366 /**
367  * Operations involving NaN's must return NaN.
368  * They are NOT exact.
369  */
370 #define handle_NAN(a, b, result) \
371 do {                                                      \
372   if (a->clss == FC_NAN) {                                \
373     if (a != result) memcpy(result, a, calc_buffer_size); \
374     fc_exact = 0;                                         \
375     return;                                               \
376   }                                                       \
377   if (b->clss == FC_NAN) {                                \
378     if (b != result) memcpy(result, b, calc_buffer_size); \
379     fc_exact = 0;                                         \
380     return;                                               \
381   }                                                       \
382 }while (0)
383
384
385 /**
386  * calculate a + b, where a is the value with the bigger exponent
387  */
388 static void _fadd(const fp_value *a, const fp_value *b, fp_value *result)
389 {
390         char *temp;
391         char *exp_diff;
392
393         char sign, res_sign;
394         char sticky;
395
396         fc_exact = 1;
397
398         handle_NAN(a, b, result);
399
400         /* make sure result has a descriptor */
401         if (result != a && result != b)
402                 result->desc = a->desc;
403
404         /* determine if this is an addition or subtraction */
405         sign = a->sign ^ b->sign;
406
407         /* produce NaN on inf - inf */
408         if (sign && (a->clss == FC_INF) && (b->clss == FC_INF)) {
409                 fc_exact = 0;
410                 fc_get_qnan(&a->desc, result);
411                 return;
412         }
413
414         temp     = (char*) alloca(value_size);
415         exp_diff = (char*) alloca(value_size);
416
417         /* get exponent difference */
418         sc_sub(_exp(a), _exp(b), exp_diff);
419
420         /* initially set sign to be the sign of a, special treatment of subtraction
421          * when exponents are equal is required though.
422          * Also special care about the sign is needed when the mantissas are equal
423          * (+/- 0 ?) */
424         if (sign && sc_val_to_long(exp_diff) == 0) {
425                 switch (sc_comp(_mant(a), _mant(b))) {
426                 case ir_relation_greater:  /* a > b */
427                         res_sign = a->sign;  /* abs(a) is bigger and a is negative */
428                         break;
429                 case ir_relation_equal:  /* a == b */
430                         res_sign = (rounding_mode == FC_TONEGATIVE);
431                         break;
432                 case ir_relation_less: /* a < b */
433                         res_sign = b->sign; /* abs(b) is bigger and b is negative */
434                         break;
435                 default:
436                         panic("invalid comparison result");
437                 }
438         }
439         else
440                 res_sign = a->sign;
441         result->sign = res_sign;
442
443         /* sign has been taken care of, check for special cases */
444         if (a->clss == FC_ZERO || b->clss == FC_INF) {
445                 if (b != result)
446                         memcpy(result, b, calc_buffer_size);
447                 fc_exact = b->clss == FC_NORMAL;
448                 result->sign = res_sign;
449                 return;
450         }
451         if (b->clss == FC_ZERO || a->clss == FC_INF) {
452                 if (a != result)
453                         memcpy(result, a, calc_buffer_size);
454                 fc_exact = a->clss == FC_NORMAL;
455                 result->sign = res_sign;
456                 return;
457         }
458
459         /* shift the smaller value to the right to align the radix point */
460         /* subnormals have their radix point shifted to the right,
461          * take care of this first */
462         if ((b->clss == FC_SUBNORMAL) && (a->clss != FC_SUBNORMAL)) {
463                 sc_val_from_ulong(1, temp);
464                 sc_sub(exp_diff, temp, exp_diff);
465         }
466
467         _shift_right(_mant(b), exp_diff, temp);
468         sticky = sc_had_carry();
469         fc_exact &= !sticky;
470
471         if (sticky && sign) {
472                 /* if subtracting a little more than the represented value or adding a little
473                  * more than the represented value to a negative value this, in addition to the
474                  * still set sticky bit, takes account of the 'little more' */
475                 char *temp1 = (char*) alloca(calc_buffer_size);
476                 sc_val_from_ulong(1, temp1);
477                 sc_add(temp, temp1, temp);
478         }
479
480         if (sign) {
481                 if (sc_comp(_mant(a), temp) == ir_relation_less)
482                         sc_sub(temp, _mant(a), _mant(result));
483                 else
484                         sc_sub(_mant(a), temp, _mant(result));
485         } else {
486                 sc_add(_mant(a), temp, _mant(result));
487         }
488
489         /* _normalize expects a 'normal' radix point, adding two subnormals
490          * results in a subnormal radix point -> shifting before normalizing */
491         if ((a->clss == FC_SUBNORMAL) && (b->clss == FC_SUBNORMAL)) {
492                 sc_val_from_ulong(1, NULL);
493                 _shift_left(_mant(result), sc_get_buffer(), _mant(result));
494         }
495
496         /* resulting exponent is the bigger one */
497         memmove(_exp(result), _exp(a), value_size);
498
499         fc_exact &= normalize(result, result, sticky);
500 }
501
502 /**
503  * calculate a * b
504  */
505 static void _fmul(const fp_value *a, const fp_value *b, fp_value *result)
506 {
507         int sticky;
508         char *temp;
509         char res_sign;
510
511         fc_exact = 1;
512
513         handle_NAN(a, b, result);
514
515         temp = (char*) alloca(value_size);
516
517         if (result != a && result != b)
518                 result->desc = a->desc;
519
520         result->sign = res_sign = a->sign ^ b->sign;
521
522         /* produce NaN on 0 * inf */
523         if (a->clss == FC_ZERO) {
524                 if (b->clss == FC_INF) {
525                         fc_get_qnan(&a->desc, result);
526                         fc_exact = 0;
527                 } else {
528                         if (a != result)
529                                 memcpy(result, a, calc_buffer_size);
530                         result->sign = res_sign;
531                 }
532                 return;
533         }
534         if (b->clss == FC_ZERO) {
535                 if (a->clss == FC_INF) {
536                         fc_get_qnan(&a->desc, result);
537                         fc_exact = 0;
538                 } else {
539                         if (b != result)
540                                 memcpy(result, b, calc_buffer_size);
541                         result->sign = res_sign;
542                 }
543                 return;
544         }
545
546         if (a->clss == FC_INF) {
547                 fc_exact = 0;
548                 if (a != result)
549                         memcpy(result, a, calc_buffer_size);
550                 result->sign = res_sign;
551                 return;
552         }
553         if (b->clss == FC_INF) {
554                 fc_exact = 0;
555                 if (b != result)
556                         memcpy(result, b, calc_buffer_size);
557                 result->sign = res_sign;
558                 return;
559         }
560
561         /* exp = exp(a) + exp(b) - excess */
562         sc_add(_exp(a), _exp(b), _exp(result));
563
564         sc_val_from_ulong((1 << (a->desc.exponent_size - 1)) - 1, temp);
565         sc_sub(_exp(result), temp, _exp(result));
566
567         /* mixed normal, subnormal values introduce an error of 1, correct it */
568         if ((a->clss == FC_SUBNORMAL) ^ (b->clss == FC_SUBNORMAL)) {
569                 sc_val_from_ulong(1, temp);
570                 sc_add(_exp(result), temp, _exp(result));
571         }
572
573         sc_mul(_mant(a), _mant(b), _mant(result));
574
575         /* realign result: after a multiplication the digits right of the radix
576          * point are the sum of the factors' digits after the radix point. As all
577          * values are normalized they both have the same amount of these digits,
578          * which has to be restored by proper shifting
579          * because of the rounding bits */
580         sc_val_from_ulong(ROUNDING_BITS + result->desc.mantissa_size, temp);
581
582         _shift_right(_mant(result), temp, _mant(result));
583         sticky = sc_had_carry();
584         fc_exact &= !sticky;
585
586         fc_exact &= normalize(result, result, sticky);
587 }
588
589 /**
590  * calculate a / b
591  */
592 static void _fdiv(const fp_value *a, const fp_value *b, fp_value *result)
593 {
594         int sticky;
595         char *temp, *dividend;
596         char res_sign;
597
598         fc_exact = 1;
599
600         handle_NAN(a, b, result);
601
602         temp = (char*) alloca(value_size);
603         dividend = (char*) alloca(value_size);
604
605         if (result != a && result != b)
606                 result->desc = a->desc;
607
608         result->sign = res_sign = a->sign ^ b->sign;
609
610         /* produce FC_NAN on 0/0 and inf/inf */
611         if (a->clss == FC_ZERO) {
612                 if (b->clss == FC_ZERO) {
613                         /* 0/0 -> NaN */
614                         fc_get_qnan(&a->desc, result);
615                         fc_exact = 0;
616                 } else {
617                         /* 0/x -> a */
618                         if (a != result)
619                                 memcpy(result, a, calc_buffer_size);
620                         result->sign = res_sign;
621                 }
622                 return;
623         }
624
625         if (b->clss == FC_INF) {
626                 fc_exact = 0;
627                 if (a->clss == FC_INF) {
628                         /* inf/inf -> NaN */
629                         fc_get_qnan(&a->desc, result);
630                 } else {
631                         /* x/inf -> 0 */
632                         sc_val_from_ulong(0, NULL);
633                         _save_result(_exp(result));
634                         _save_result(_mant(result));
635                         result->clss = FC_ZERO;
636                 }
637                 return;
638         }
639
640         if (a->clss == FC_INF) {
641                 fc_exact = 0;
642                 /* inf/x -> inf */
643                 if (a != result)
644                         memcpy(result, a, calc_buffer_size);
645                 result->sign = res_sign;
646                 return;
647         }
648         if (b->clss == FC_ZERO) {
649                 fc_exact = 0;
650                 /* division by zero */
651                 if (result->sign)
652                         fc_get_minusinf(&a->desc, result);
653                 else
654                         fc_get_plusinf(&a->desc, result);
655                 return;
656         }
657
658         /* exp = exp(a) - exp(b) + excess - 1*/
659         sc_sub(_exp(a), _exp(b), _exp(result));
660         sc_val_from_ulong((1 << (a->desc.exponent_size - 1)) - 2, temp);
661         sc_add(_exp(result), temp, _exp(result));
662
663         /* mixed normal, subnormal values introduce an error of 1, correct it */
664         if ((a->clss == FC_SUBNORMAL) ^ (b->clss == FC_SUBNORMAL)) {
665                 sc_val_from_ulong(1, temp);
666                 sc_add(_exp(result), temp, _exp(result));
667         }
668
669         /* mant(res) = mant(a) / 1/2mant(b) */
670         /* to gain more bits of precision in the result the dividend could be
671          * shifted left, as this operation does not loose bits. This would not
672          * fit into the integer precision, but due to the rounding bits (which
673          * are always zero because the values are all normalized) the divisor
674          * can be shifted right instead to achieve the same result */
675         sc_val_from_ulong(ROUNDING_BITS + result->desc.mantissa_size, temp);
676
677         _shift_left(_mant(a), temp, dividend);
678
679         {
680                 char *divisor = (char*) alloca(calc_buffer_size);
681                 sc_val_from_ulong(1, divisor);
682                 _shift_right(_mant(b), divisor, divisor);
683                 sc_div(dividend, divisor, _mant(result));
684                 sticky = sc_had_carry();
685                 fc_exact &= !sticky;
686         }
687
688         fc_exact &= normalize(result, result, sticky);
689 }
690
691 /**
692  * Truncate the fractional part away.
693  *
694  * This does not clip to any integer range.
695  */
696 static void _trunc(const fp_value *a, fp_value *result)
697 {
698         /*
699          * When exponent == 0 all bits left of the radix point
700          * are the integral part of the value. For 15bit exp_size
701          * this would require a left shift of max. 16383 bits which
702          * is too much.
703          * But it is enough to ensure that no bit right of the radix
704          * point remains set. This restricts the interesting
705          * exponents to the interval [0, mant_size-1].
706          * Outside this interval the truncated value is either 0 or
707          * it does not have fractional parts.
708          */
709
710         int exp_bias, exp_val;
711         char *temp;
712
713         /* fixme: can be exact */
714         fc_exact = 0;
715
716         temp = (char*) alloca(value_size);
717
718         if (a != result) {
719                 result->desc = a->desc;
720                 result->clss = a->clss;
721         }
722
723         exp_bias = (1 << (a->desc.exponent_size - 1)) - 1;
724         exp_val  = sc_val_to_long(_exp(a)) - exp_bias;
725
726         if (exp_val < 0) {
727                 sc_val_from_ulong(0, NULL);
728                 _save_result(_exp(result));
729                 _save_result(_mant(result));
730                 result->clss = FC_ZERO;
731
732                 return;
733         }
734
735         if (exp_val > (long)a->desc.mantissa_size) {
736                 if (a != result)
737                         memcpy(result, a, calc_buffer_size);
738
739                 return;
740         }
741
742         /* set up a proper mask to delete all bits right of the
743          * radix point if the mantissa had been shifted until exp == 0 */
744         sc_max_from_bits(1 + exp_val, 0, temp);
745         sc_val_from_long(a->desc.mantissa_size - exp_val + 2, NULL);
746         _shift_left(temp, sc_get_buffer(), temp);
747
748         /* and the mask and return the result */
749         sc_and(_mant(a), temp, _mant(result));
750
751         if (a != result) {
752                 memcpy(_exp(result), _exp(a), value_size);
753                 result->sign = a->sign;
754         }
755 }
756
757 /********
758  * functions defined in fltcalc.h
759  ********/
760 const void *fc_get_buffer(void)
761 {
762         return calc_buffer;
763 }
764
765 int fc_get_buffer_length(void)
766 {
767         return calc_buffer_size;
768 }
769
770 void *fc_val_from_str(const char *str, size_t len,
771                       const float_descriptor_t *desc, void *result)
772 {
773         char *buffer;
774
775         /* XXX excuse of an implementation to make things work */
776         long double        val;
777         fp_value          *tmp = (fp_value*) alloca(calc_buffer_size);
778         float_descriptor_t tmp_desc;
779
780         buffer = (char*) alloca(len+1);
781         memcpy(buffer, str, len);
782         buffer[len] = '\0';
783         val = string_to_long_double(buffer);
784
785         tmp_desc.exponent_size = 15;
786         tmp_desc.mantissa_size = 63;
787         tmp_desc.explicit_one  = 1;
788         fc_val_from_ieee754(val, &tmp_desc, tmp);
789
790         return fc_cast(tmp, desc, (fp_value*) result);
791 }
792
793 fp_value *fc_val_from_ieee754(long double l, const float_descriptor_t *desc,
794                               fp_value *result)
795 {
796         char    *temp;
797         int      bias_res, bias_val, mant_val;
798         value_t  srcval;
799         char     sign;
800         uint32_t exponent, mantissa0, mantissa1;
801         size_t   long_double_size = sizeof(long double);
802
803         srcval.d = l;
804         bias_res = ((1 << (desc->exponent_size - 1)) - 1);
805
806         if (long_double_size == 8) {
807                 mant_val  = 52;
808                 bias_val  = 0x3ff;
809                 sign      = (srcval.val_ld8.high & 0x80000000) != 0;
810                 exponent  = (srcval.val_ld8.high & 0x7FF00000) >> 20;
811                 mantissa0 = srcval.val_ld8.high & 0x000FFFFF;
812                 mantissa1 = srcval.val_ld8.low;
813         } else {
814                 /* we assume an x86-like 80bit representation of the value... */
815                 assert(sizeof(long double)==12 || sizeof(long double)==16);
816                 mant_val  = 63;
817                 bias_val  = 0x3fff;
818                 sign      = (srcval.val_ld12.high & 0x00008000) != 0;
819                 exponent  = (srcval.val_ld12.high & 0x00007FFF) ;
820                 mantissa0 = srcval.val_ld12.mid;
821                 mantissa1 = srcval.val_ld12.low;
822         }
823
824         if (result == NULL)
825                 result = calc_buffer;
826         temp = (char*) alloca(value_size);
827
828         /* CLEAR the buffer, else some bits might be uninitialized */
829         memset(result, 0, fc_get_buffer_length());
830
831         result->desc = *desc;
832         result->clss = FC_NORMAL;
833         result->sign = sign;
834
835         /* sign and flag suffice to identify NaN or inf, no exponent/mantissa
836          * encoding is needed. the function can return immediately in these cases */
837         if (my_isnan(l)) {
838                 result->clss = FC_NAN;
839                 return result;
840         } else if (my_isinf(l)) {
841                 result->clss = FC_INF;
842                 return result;
843         }
844
845         /* build exponent, because input and output exponent and mantissa sizes may differ
846          * this looks more complicated than it is: unbiased input exponent + output bias,
847          * minus the mantissa difference which is added again later when the output float
848          * becomes normalized */
849         sc_val_from_long((exponent - bias_val + bias_res) - (mant_val - desc->mantissa_size), _exp(result));
850
851         /* build mantissa representation */
852         if (exponent != 0) {
853                 /* insert the hidden bit */
854                 sc_val_from_ulong(1, temp);
855                 sc_val_from_ulong(mant_val + ROUNDING_BITS, NULL);
856                 _shift_left(temp, sc_get_buffer(), NULL);
857         }
858         else {
859                 sc_val_from_ulong(0, NULL);
860         }
861
862         _save_result(_mant(result));
863
864         /* bits from the upper word */
865         sc_val_from_ulong(mantissa0, temp);
866         sc_val_from_ulong(34, NULL);
867         _shift_left(temp, sc_get_buffer(), temp);
868         sc_or(_mant(result), temp, _mant(result));
869
870         /* bits from the lower word */
871         sc_val_from_ulong(mantissa1, temp);
872         sc_val_from_ulong(ROUNDING_BITS, NULL);
873         _shift_left(temp, sc_get_buffer(), temp);
874         sc_or(_mant(result), temp, _mant(result));
875
876         /* _normalize expects the radix point to be normal, so shift mantissa of subnormal
877          * origin one to the left */
878         if (exponent == 0) {
879                 sc_val_from_ulong(1, NULL);
880                 _shift_left(_mant(result), sc_get_buffer(), _mant(result));
881         }
882
883         normalize(result, result, 0);
884
885         return result;
886 }
887
888 long double fc_val_to_ieee754(const fp_value *val)
889 {
890         fp_value *value;
891         fp_value *temp = NULL;
892
893         unsigned byte_offset;
894
895         uint32_t sign;
896         uint32_t exponent;
897         uint32_t mantissa0;
898         uint32_t mantissa1;
899
900         value_t           buildval;
901         float_descriptor_t desc;
902         unsigned          mantissa_size;
903
904         size_t            long_double_size = sizeof(long double);
905
906         if (long_double_size == 8) {
907                 desc.exponent_size = 11;
908                 desc.mantissa_size = 52;
909                 desc.explicit_one  = 0;
910         } else {
911                 desc.exponent_size = 15;
912                 desc.mantissa_size = 63;
913                 desc.explicit_one  = 1;
914         }
915         mantissa_size = desc.mantissa_size + desc.explicit_one;
916
917         temp = (fp_value*) alloca(calc_buffer_size);
918         value = fc_cast(val, &desc, temp);
919
920         sign = value->sign;
921
922         /* @@@ long double exponent is 15bit, so the use of sc_val_to_long should not
923          * lead to wrong results */
924         exponent = sc_val_to_long(_exp(value)) ;
925
926         sc_val_from_ulong(ROUNDING_BITS, NULL);
927         _shift_right(_mant(value), sc_get_buffer(), _mant(value));
928
929         mantissa0 = 0;
930         mantissa1 = 0;
931
932         for (byte_offset = 0; byte_offset < 4; byte_offset++)
933                 mantissa1 |= sc_sub_bits(_mant(value), mantissa_size, byte_offset) << (byte_offset << 3);
934
935         for (; (byte_offset<<3) < desc.mantissa_size; byte_offset++)
936                 mantissa0 |= sc_sub_bits(_mant(value), mantissa_size, byte_offset) << ((byte_offset - 4) << 3);
937
938         if (long_double_size == 8) {
939                 mantissa0 &= 0x000FFFFF;  /* get rid of garbage */
940                 buildval.val_ld8.high = sign << 31;
941                 buildval.val_ld8.high |= exponent << 20;
942                 buildval.val_ld8.high |= mantissa0;
943                 buildval.val_ld8.low = mantissa1;
944         } else {
945                 buildval.val_ld12.high = sign << 15;
946                 buildval.val_ld12.high |= exponent;
947                 buildval.val_ld12.mid = mantissa0;
948                 buildval.val_ld12.low = mantissa1;
949         }
950
951         return buildval.d;
952 }
953
954 fp_value *fc_cast(const fp_value *value, const float_descriptor_t *desc,
955                   fp_value *result)
956 {
957         char *temp;
958         int exp_offset, val_bias, res_bias;
959
960         if (result == NULL) result = calc_buffer;
961         temp = (char*) alloca(value_size);
962
963         if (value->desc.exponent_size == desc->exponent_size &&
964                 value->desc.mantissa_size == desc->mantissa_size &&
965                 value->desc.explicit_one  == desc->explicit_one) {
966                 if (value != result)
967                         memcpy(result, value, calc_buffer_size);
968                 return result;
969         }
970
971         if (value->clss == FC_NAN) {
972                 if (sc_get_highest_set_bit(_mant(value)) == value->desc.mantissa_size + 1)
973                         return fc_get_qnan(desc, result);
974                 else
975                         return fc_get_snan(desc, result);
976         }
977         else if (value->clss == FC_INF) {
978                 if (value->sign == 0)
979                         return fc_get_plusinf(desc, result);
980                 else
981                         return fc_get_minusinf(desc, result);
982         }
983
984         /* set the descriptor of the new value */
985         result->desc = *desc;
986         result->clss = value->clss;
987         result->sign = value->sign;
988
989         /* when the mantissa sizes differ normalizing has to shift to align it.
990          * this would change the exponent, which is unwanted. So calculate this
991          * offset and add it */
992         val_bias = (1 << (value->desc.exponent_size - 1)) - 1;
993         res_bias = (1 << (desc->exponent_size - 1)) - 1;
994
995         exp_offset = (res_bias - val_bias) - (value->desc.mantissa_size - desc->mantissa_size);
996         sc_val_from_long(exp_offset, temp);
997         sc_add(_exp(value), temp, _exp(result));
998
999         /* _normalize expects normalized radix point */
1000         if (value->clss == FC_SUBNORMAL) {
1001                 sc_val_from_ulong(1, NULL);
1002                 _shift_left(_mant(value), sc_get_buffer(), _mant(result));
1003         } else if (value != result) {
1004                 memcpy(_mant(result), _mant(value), value_size);
1005         } else {
1006                 memmove(_mant(result), _mant(value), value_size);
1007         }
1008
1009         normalize(result, result, 0);
1010         return result;
1011 }
1012
1013 fp_value *fc_get_max(const float_descriptor_t *desc, fp_value *result)
1014 {
1015         if (result == NULL) result = calc_buffer;
1016
1017         result->desc = *desc;
1018         result->clss = FC_NORMAL;
1019         result->sign = 0;
1020
1021         sc_val_from_ulong((1 << desc->exponent_size) - 2, _exp(result));
1022
1023         sc_max_from_bits(desc->mantissa_size + 1, 0, _mant(result));
1024         sc_val_from_ulong(ROUNDING_BITS, NULL);
1025         _shift_left(_mant(result), sc_get_buffer(), _mant(result));
1026
1027         return result;
1028 }
1029
1030 fp_value *fc_get_min(const float_descriptor_t *desc, fp_value *result)
1031 {
1032         if (result == NULL) result = calc_buffer;
1033
1034         fc_get_max(desc, result);
1035         result->sign = 1;
1036
1037         return result;
1038 }
1039
1040 fp_value *fc_get_snan(const float_descriptor_t *desc, fp_value *result)
1041 {
1042         if (result == NULL) result = calc_buffer;
1043
1044         result->desc = *desc;
1045         result->clss = FC_NAN;
1046         result->sign = 0;
1047
1048         sc_val_from_ulong((1 << desc->exponent_size) - 1, _exp(result));
1049
1050         /* signaling NaN has non-zero mantissa with msb not set */
1051         sc_val_from_ulong(1, _mant(result));
1052
1053         return result;
1054 }
1055
1056 fp_value *fc_get_qnan(const float_descriptor_t *desc, fp_value *result)
1057 {
1058         if (result == NULL) result = calc_buffer;
1059
1060         result->desc = *desc;
1061         result->clss = FC_NAN;
1062         result->sign = 0;
1063
1064         sc_val_from_ulong((1 << desc->exponent_size) - 1, _exp(result));
1065
1066         /* quiet NaN has the msb of the mantissa set, so shift one there */
1067         sc_val_from_ulong(1, _mant(result));
1068         /* mantissa_size >+< 1 because of two extra rounding bits */
1069         sc_val_from_ulong(desc->mantissa_size + 1, NULL);
1070         _shift_left(_mant(result), sc_get_buffer(), _mant(result));
1071
1072         return result;
1073 }
1074
1075 fp_value *fc_get_plusinf(const float_descriptor_t *desc, fp_value *result)
1076 {
1077         char *mant;
1078
1079         if (result == NULL) result = calc_buffer;
1080
1081         result->desc = *desc;
1082         result->clss = FC_INF;
1083         result->sign = 0;
1084
1085         sc_val_from_ulong((1 << desc->exponent_size) - 1, _exp(result));
1086
1087         mant = _mant(result);
1088         sc_val_from_ulong(0, mant);
1089         if (desc->explicit_one) {
1090                 sc_set_bit_at(mant, result->desc.mantissa_size + ROUNDING_BITS);
1091         }
1092
1093         return result;
1094 }
1095
1096 fp_value *fc_get_minusinf(const float_descriptor_t *desc, fp_value *result)
1097 {
1098         if (result == NULL) result = calc_buffer;
1099
1100         fc_get_plusinf(desc, result);
1101         result->sign = 1;
1102
1103         return result;
1104 }
1105
1106 ir_relation fc_comp(fp_value const *const val_a, fp_value const *const val_b)
1107 {
1108         /*
1109          * shortcut: if both values are identical, they are either
1110          * Unordered if NaN or equal
1111          */
1112         if (val_a == val_b)
1113                 return val_a->clss == FC_NAN ? ir_relation_unordered : ir_relation_equal;
1114
1115         /* unordered if one is a NaN */
1116         if (val_a->clss == FC_NAN || val_b->clss == FC_NAN)
1117                 return ir_relation_unordered;
1118
1119         /* zero is equal independent of sign */
1120         if ((val_a->clss == FC_ZERO) && (val_b->clss == FC_ZERO))
1121                 return ir_relation_equal;
1122
1123         /* different signs make compare easy */
1124         if (val_a->sign != val_b->sign)
1125                 return val_a->sign == 0 ? ir_relation_greater : ir_relation_less;
1126
1127         ir_relation const mul = val_a->sign ? ir_relation_less_greater : ir_relation_false;
1128
1129         /* both infinity means equality */
1130         if ((val_a->clss == FC_INF) && (val_b->clss == FC_INF))
1131                 return ir_relation_equal;
1132
1133         /* infinity is bigger than the rest */
1134         if (val_a->clss == FC_INF)
1135                 return ir_relation_greater ^ mul;
1136         if (val_b->clss == FC_INF)
1137                 return ir_relation_less ^ mul;
1138
1139         /* check first exponent, that mantissa if equal */
1140         ir_relation rel = sc_comp(_exp(val_a), _exp(val_b));
1141         if (rel == ir_relation_equal)
1142                 rel = sc_comp(_mant(val_a), _mant(val_b));
1143         if (rel != ir_relation_equal)
1144                 rel ^= mul;
1145         return rel;
1146 }
1147
1148 int fc_is_zero(const fp_value *a)
1149 {
1150         return a->clss == FC_ZERO;
1151 }
1152
1153 int fc_is_negative(const fp_value *a)
1154 {
1155         return a->sign;
1156 }
1157
1158 int fc_is_inf(const fp_value *a)
1159 {
1160         return a->clss == FC_INF;
1161 }
1162
1163 int fc_is_nan(const fp_value *a)
1164 {
1165         return a->clss == FC_NAN;
1166 }
1167
1168 int fc_is_subnormal(const fp_value *a)
1169 {
1170         return a->clss == FC_SUBNORMAL;
1171 }
1172
1173 char *fc_print(const fp_value *val, char *buf, int buflen, unsigned base)
1174 {
1175         char *mul_1;
1176         long double flt_val;
1177
1178         mul_1 = (char*) alloca(calc_buffer_size);
1179
1180         switch (base) {
1181         case FC_DEC:
1182                 switch ((value_class_t)val->clss) {
1183                 case FC_INF:
1184                         snprintf(buf, buflen, "%cINF", val->sign ? '-' : '+');
1185                         break;
1186                 case FC_NAN:
1187                         snprintf(buf, buflen, "NaN");
1188                         break;
1189                 case FC_ZERO:
1190                         snprintf(buf, buflen, "0.0");
1191                         break;
1192                 default:
1193                         flt_val = fc_val_to_ieee754(val);
1194                         /* XXX 30 is arbitrary */
1195                         snprintf(buf, buflen, "%.30LE", flt_val);
1196                 }
1197                 break;
1198
1199         case FC_HEX:
1200                 switch ((value_class_t)val->clss) {
1201                 case FC_INF:
1202                         snprintf(buf, buflen, "%cINF", val->sign ? '-' : '+');
1203                         break;
1204                 case FC_NAN:
1205                         snprintf(buf, buflen, "NaN");
1206                         break;
1207                 case FC_ZERO:
1208                         snprintf(buf, buflen, "0.0");
1209                         break;
1210                 default:
1211                         flt_val = fc_val_to_ieee754(val);
1212                         snprintf(buf, buflen, "%LA", flt_val);
1213                 }
1214                 break;
1215
1216         case FC_PACKED:
1217         default:
1218                 snprintf(buf, buflen, "%s", sc_print(pack(val, mul_1), value_size*4, SC_HEX, 0));
1219                 buf[buflen - 1] = '\0';
1220                 break;
1221         }
1222         return buf;
1223 }
1224
1225 unsigned char fc_sub_bits(const fp_value *value, unsigned num_bits, unsigned byte_ofs)
1226 {
1227         /* this is used to cache the packed version of the value */
1228         static char *packed_value = NULL;
1229
1230         if (packed_value == NULL) packed_value = XMALLOCN(char, value_size);
1231
1232         if (value != NULL)
1233                 pack(value, packed_value);
1234
1235         return sc_sub_bits(packed_value, num_bits, byte_ofs);
1236 }
1237
1238 /* Returns non-zero if the mantissa is zero, i.e. 1.0Exxx */
1239 int fc_zero_mantissa(const fp_value *value)
1240 {
1241         return sc_get_lowest_set_bit(_mant(value)) == ROUNDING_BITS + value->desc.mantissa_size;
1242 }
1243
1244 /* Returns the exponent of a value. */
1245 int fc_get_exponent(const fp_value *value)
1246 {
1247         int exp_bias = (1 << (value->desc.exponent_size - 1)) - 1;
1248         return sc_val_to_long(_exp(value)) - exp_bias;
1249 }
1250
1251 /* Return non-zero if a given value can be converted lossless into another precision */
1252 int fc_can_lossless_conv_to(const fp_value *value, const float_descriptor_t *desc)
1253 {
1254         int v;
1255         int exp_bias;
1256
1257         /* handle some special cases first */
1258         switch (value->clss) {
1259         case FC_ZERO:
1260         case FC_INF:
1261         case FC_NAN:
1262                 return 1;
1263         default:
1264                 break;
1265         }
1266
1267         /* check if the exponent can be encoded: note, 0 and all ones are reserved for the exponent */
1268         exp_bias = (1 << (desc->exponent_size - 1)) - 1;
1269         v = fc_get_exponent(value) + exp_bias;
1270         if (0 < v && v < (1 << desc->exponent_size) - 1) {
1271                 /* exponent can be encoded, now check the mantissa */
1272                 v = value->desc.mantissa_size + ROUNDING_BITS - sc_get_lowest_set_bit(_mant(value));
1273                 return v <= (int)desc->mantissa_size;
1274         }
1275         return 0;
1276 }
1277
1278
1279 fc_rounding_mode_t fc_set_rounding_mode(fc_rounding_mode_t mode)
1280 {
1281         if (mode == FC_TONEAREST || mode == FC_TOPOSITIVE || mode == FC_TONEGATIVE || mode == FC_TOZERO)
1282                 rounding_mode = mode;
1283
1284         return rounding_mode;
1285 }
1286
1287 fc_rounding_mode_t fc_get_rounding_mode(void)
1288 {
1289         return rounding_mode;
1290 }
1291
1292 void init_fltcalc(int precision)
1293 {
1294         if (calc_buffer == NULL) {
1295                 /* does nothing if already init */
1296                 if (precision == 0) precision = FC_DEFAULT_PRECISION;
1297
1298                 init_strcalc(precision + 2 + ROUNDING_BITS);
1299
1300                 /* needs additionally rounding bits, one bit as explicit 1., and one for
1301                  * addition overflow */
1302                 max_precision = sc_get_precision() - (2 + ROUNDING_BITS);
1303                 if (max_precision < precision)
1304                         printf("WARNING: not enough precision available, using %d\n", max_precision);
1305
1306                 rounding_mode    = FC_TONEAREST;
1307                 value_size       = sc_get_buffer_length();
1308                 calc_buffer_size = sizeof(fp_value) + 2*value_size - 1;
1309
1310                 calc_buffer = (fp_value*) xmalloc(calc_buffer_size);
1311                 memset(calc_buffer, 0, calc_buffer_size);
1312         }
1313 }
1314
1315 void finish_fltcalc (void)
1316 {
1317         free(calc_buffer); calc_buffer = NULL;
1318 }
1319
1320 /* definition of interface functions */
1321 fp_value *fc_add(const fp_value *a, const fp_value *b, fp_value *result)
1322 {
1323         if (result == NULL) result = calc_buffer;
1324
1325         /* make the value with the bigger exponent the first one */
1326         if (sc_comp(_exp(a), _exp(b)) == ir_relation_less)
1327                 _fadd(b, a, result);
1328         else
1329                 _fadd(a, b, result);
1330
1331         return result;
1332 }
1333
1334 fp_value *fc_sub(const fp_value *a, const fp_value *b, fp_value *result)
1335 {
1336         fp_value *temp;
1337
1338         if (result == NULL) result = calc_buffer;
1339
1340         temp = (fp_value*) alloca(calc_buffer_size);
1341         memcpy(temp, b, calc_buffer_size);
1342         temp->sign = !b->sign;
1343         if (sc_comp(_exp(a), _exp(temp)) == ir_relation_less)
1344                 _fadd(temp, a, result);
1345         else
1346                 _fadd(a, temp, result);
1347
1348         return result;
1349 }
1350
1351 fp_value *fc_mul(const fp_value *a, const fp_value *b, fp_value *result)
1352 {
1353         if (result == NULL) result = calc_buffer;
1354
1355         _fmul(a, b, result);
1356
1357         return result;
1358 }
1359
1360 fp_value *fc_div(const fp_value *a, const fp_value *b, fp_value *result)
1361 {
1362         if (result == NULL) result = calc_buffer;
1363
1364         _fdiv(a, b, result);
1365
1366         return result;
1367 }
1368
1369 fp_value *fc_neg(const fp_value *a, fp_value *result)
1370 {
1371         if (result == NULL) result = calc_buffer;
1372
1373         if (a != result)
1374                 memcpy(result, a, calc_buffer_size);
1375         result->sign = !a->sign;
1376
1377         return result;
1378 }
1379
1380 fp_value *fc_int(const fp_value *a, fp_value *result)
1381 {
1382         if (result == NULL) result = calc_buffer;
1383
1384         _trunc(a, result);
1385
1386         return result;
1387 }
1388
1389 fp_value *fc_rnd(const fp_value *a, fp_value *result)
1390 {
1391         (void)a;
1392         (void)result;
1393
1394         panic("not yet implemented");
1395 }
1396
1397 /*
1398  * convert a floating point value into an sc value ...
1399  */
1400 int fc_flt2int(const fp_value *a, void *result, ir_mode *dst_mode)
1401 {
1402         if (a->clss == FC_NORMAL) {
1403                 int exp_bias = (1 << (a->desc.exponent_size - 1)) - 1;
1404                 int exp_val  = sc_val_to_long(_exp(a)) - exp_bias;
1405                 int shift, highest;
1406                 int mantissa_size;
1407                 int tgt_bits;
1408
1409                 if (a->sign && !mode_is_signed(dst_mode)) {
1410                         /* FIXME: for now we cannot convert this */
1411                         return 0;
1412                 }
1413
1414                 tgt_bits = get_mode_size_bits(dst_mode);
1415                 if (mode_is_signed(dst_mode))
1416                         --tgt_bits;
1417
1418                 assert(exp_val >= 0 && "floating point value not integral before fc_flt2int() call");
1419                 mantissa_size = a->desc.mantissa_size + ROUNDING_BITS;
1420                 shift         = exp_val - mantissa_size;
1421
1422                 if (tgt_bits < mantissa_size + 1)
1423                         tgt_bits = mantissa_size + 1;
1424                 if (shift > 0) {
1425                         sc_shlI(_mant(a),  shift, tgt_bits, 0, result);
1426                 } else {
1427                         sc_shrI(_mant(a), -shift, tgt_bits, 0, result);
1428                 }
1429
1430                 /* check for overflow */
1431                 highest = sc_get_highest_set_bit(result);
1432
1433                 if (mode_is_signed(dst_mode)) {
1434                         if (highest == sc_get_lowest_set_bit(result)) {
1435                                 /* need extra test for MIN_INT */
1436                                 if (highest >= (int) get_mode_size_bits(dst_mode)) {
1437                                         /* FIXME: handle overflow */
1438                                         return 0;
1439                                 }
1440                         } else {
1441                                 if (highest >= (int) get_mode_size_bits(dst_mode) - 1) {
1442                                         /* FIXME: handle overflow */
1443                                         return 0;
1444                                 }
1445                         }
1446                 } else {
1447                         if (highest >= (int) get_mode_size_bits(dst_mode)) {
1448                                 /* FIXME: handle overflow */
1449                                 return 0;
1450                         }
1451                 }
1452
1453                 if (a->sign)
1454                         sc_neg(result, result);
1455
1456                 return 1;
1457         } else if (a->clss == FC_ZERO) {
1458                 sc_zero(result);
1459                 return 1;
1460         }
1461         return 0;
1462 }
1463
1464 int fc_is_exact(void)
1465 {
1466         return fc_exact;
1467 }