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