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