replaced inline by __inline to allow to be compiled in gcc and msvc modes
[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   if (result == NULL) result = calc_buffer;
919
920   exp_val = alloca(value_size);
921   power_val = alloca(calc_buffer_size);
922   mant_str = alloca((len)?(len):(strlen(str)));
923
924   _desc(result).exponent_size = exp_size;
925   _desc(result).mantissa_size = mant_size;
926   _desc(result).clss = NORMAL;
927
928   old_str = str;
929   pos = 0;
930   exp_int = 0;
931   state = START;
932
933   while (len == 0 || str-old_str < len)
934   {
935     switch (state) {
936       case START:
937         switch (*str) {
938           case '+':
939             _sign(result) = 0;
940             state = LEFT_OF_DOT;
941             str++;
942             break;
943
944           case '-':
945             _sign(result) = 1;
946             state = LEFT_OF_DOT;
947             str++;
948             break;
949
950           case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
951             _sign(result) = 0;
952             state = LEFT_OF_DOT;
953             break;
954
955           case '.':
956             _sign(result) = 0;
957             state = RIGHT_OF_DOT;
958             str++;
959             break;
960
961           case 'n':
962           case 'N':
963           case 'i':
964           case 'I':
965             break;
966
967           default:
968             _fail_char(old_str, len, str - old_str);
969         }
970         break;
971
972       case LEFT_OF_DOT:
973         switch (*str) {
974           case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
975             mant_str[pos++] = *(str++);
976             break;
977
978           case '.':
979             state = RIGHT_OF_DOT;
980             str++;
981             break;
982
983           case 'e':
984           case 'E':
985             state = EXP_START;
986             str++;
987             break;
988
989           case '\0':
990             mant_str[pos] = '\0';
991             goto done;
992
993           default:
994             _fail_char(old_str, len, str - old_str);
995         }
996         break;
997
998       case RIGHT_OF_DOT:
999         switch (*str) {
1000           case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
1001             mant_str[pos++] = *(str++);
1002             exp_int++;
1003             break;
1004
1005           case 'e':
1006           case 'E':
1007             state = EXP_START;
1008             str++;
1009             break;
1010
1011           case '\0':
1012             mant_str[pos] = '\0';
1013             goto done;
1014
1015           default:
1016             _fail_char(old_str, len, str - old_str);
1017         }
1018         break;
1019
1020       case EXP_START:
1021         switch (*str) {
1022           case '-':
1023             exp_sign = 1;
1024             /* fall through */
1025           case '+':
1026             if (*(str-1) != 'e' && *(str-1) != 'E') _fail_char(old_str, len, str - old_str);
1027             str++;
1028             break;
1029
1030           case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
1031             mant_str[pos] = '\0';
1032             pos = 1;
1033             str++;
1034             state = EXPONENT;
1035             break;
1036
1037           default:
1038             _fail_char(old_str, len, str - old_str);
1039         }
1040         break;
1041
1042       case EXPONENT:
1043         switch (*str) {
1044           case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
1045             pos++;
1046             str++;
1047             break;
1048
1049           case '\0': goto done;
1050
1051           default:
1052             _fail_char(old_str, len, str - old_str);
1053         }
1054     }
1055   } /*  switch(state) */
1056
1057 done:
1058   sc_val_from_str(mant_str, strlen(mant_str), _mant(result));
1059
1060   /* shift to put value left of radix point */
1061   sc_val_from_ulong(mant_size + 2, exp_val);
1062
1063   _shift_left(_mant(result), exp_val, _mant(result));
1064
1065   sc_val_from_ulong((1 << exp_size)/2-1, _exp(result));
1066
1067   _normalize(result, result, 0);
1068
1069   if (state == EXPONENT) {
1070     exp_int -= atoi(str-pos);
1071   }
1072
1073   _power_of_ten(exp_int, &_desc(result), power_val);
1074
1075   _fdiv(result, power_val, result);
1076
1077   return result;
1078 #else
1079
1080   /* XXX excuse of an implementation to make things work */
1081   LLDBL val;
1082 #ifdef HAVE_LONG_DOUBLE
1083   val = strtold(str, NULL);
1084 #else
1085   val = strtod(str, NULL);
1086 #endif
1087
1088   DEBUGPRINTF(("val_from_str(%s)\n", str));
1089   return fc_val_from_float(val, exp_size, mant_size, result);
1090 #endif
1091 }
1092
1093 char* fc_val_from_float(LLDBL l, char exp_size, char mant_size, char* result)
1094 {
1095   char *temp;
1096   int bias_res, bias_val, mant_val;
1097   value_t srcval;
1098   UINT32 sign, exponent, mantissa0, mantissa1;
1099
1100   srcval.d = l;
1101   bias_res = ((1<<exp_size)/2-1);
1102
1103 #ifdef HAVE_LONG_DOUBLE
1104   mant_val  = 64;
1105   bias_val  = 0x3fff;
1106   sign      = (srcval.val.high & 0x00008000) != 0;
1107   exponent  = (srcval.val.high & 0x00007FFF) ;
1108   mantissa0 = srcval.val.mid;
1109   mantissa1 = srcval.val.low;
1110 #else /* no long double */
1111   mant_val  = 52;
1112   bias_val  = 0x3ff;
1113   sign      = (srcval.val.high & 0x80000000) != 0;
1114   exponent  = (srcval.val.high & 0x7FF00000) >> 20;
1115   mantissa0 = srcval.val.high & 0x000FFFFF;
1116   mantissa1 = srcval.val.low;
1117 #endif
1118
1119 #ifdef HAVE_LONG_DOUBLE
1120   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)); */
1121   DEBUGPRINTF(("(%d-%.4X-%.8X%.8X)\n", sign, exponent, mantissa0, mantissa1));
1122 #else
1123   TRACEPRINTF(("val_from_float(%.8X%.8X)\n", srcval.val.high, srcval.val.low));
1124   DEBUGPRINTF(("(%d-%.3X-%.5X%.8X)\n", sign, exponent, mantissa0, mantissa1));
1125 #endif
1126
1127   if (result == NULL) result = calc_buffer;
1128   temp = alloca(value_size);
1129
1130   _desc(result).exponent_size = exp_size;
1131   _desc(result).mantissa_size = mant_size;
1132
1133   /* extract sign */
1134   _sign(result) = sign;
1135
1136   /* sign and flag suffice to identify nan or inf, no exponent/mantissa
1137    * encoding is needed. the function can return immediately in these cases */
1138   if (isnan(l)) {
1139     _desc(result).clss = NAN;
1140     TRACEPRINTF(("val_from_float resulted in NAN\n"));
1141     return result;
1142   }
1143   else if (isinf(l)) {
1144     _desc(result).clss = INF;
1145     TRACEPRINTF(("val_from_float resulted in %sINF\n", (_sign(result)==1)?"-":""));
1146     return result;
1147   }
1148
1149   /* build exponent, because input and output exponent and mantissa sizes may differ
1150    * this looks more complicated than it is: unbiased input exponent + output bias,
1151    * minus the mantissa difference which is added again later when the output float
1152    * becomes normalized */
1153 #ifdef HAVE_EXPLICIT_ONE
1154   sc_val_from_long((exponent-bias_val+bias_res)-(mant_val-mant_size-1), _exp(result));
1155 #else
1156   sc_val_from_long((exponent-bias_val+bias_res)-(mant_val-mant_size), _exp(result));
1157 #endif
1158
1159   /* build mantissa representation */
1160 #ifndef HAVE_EXPLICIT_ONE
1161   if (exponent != 0)
1162   {
1163     /* insert the hidden bit */
1164     sc_val_from_ulong(1, temp);
1165     sc_val_from_ulong(mant_val + 2, NULL);
1166     _shift_left(temp, sc_get_buffer(), NULL);
1167   }
1168   else
1169 #endif
1170   {
1171     sc_val_from_ulong(0, NULL);
1172   }
1173
1174   _save_result(_mant(result));
1175
1176   /* bits from the upper word */
1177   sc_val_from_ulong(mantissa0, temp);
1178   sc_val_from_ulong(34, NULL);
1179   _shift_left(temp, sc_get_buffer(), temp);
1180   sc_or(_mant(result), temp, _mant(result));
1181
1182   /* bits from the lower word */
1183   sc_val_from_ulong(mantissa1, temp);
1184   sc_val_from_ulong(2, NULL);
1185   _shift_left(temp, sc_get_buffer(), temp);
1186   sc_or(_mant(result), temp, _mant(result));
1187
1188   /* _normalize expects the radix point to be normal, so shift mantissa of subnormal
1189    * origin one to the left */
1190   if (exponent == 0)
1191   {
1192     sc_val_from_ulong(1, NULL);
1193     _shift_left(_mant(result), sc_get_buffer(), _mant(result));
1194   }
1195
1196   _normalize(result, result, 0);
1197
1198   TRACEPRINTF(("val_from_float results in %s\n", fc_print(result, temp, calc_buffer_size, FC_PACKED)));
1199
1200   return result;
1201 }
1202
1203 LLDBL fc_val_to_float(const void *val)
1204 {
1205   const char *value;
1206   char *temp = NULL;
1207
1208   int byte_offset;
1209
1210   UINT32 sign;
1211   UINT32 exponent;
1212   UINT32 mantissa0;
1213   UINT32 mantissa1;
1214
1215   value_t buildval;
1216
1217 #ifdef HAVE_LONG_DOUBLE
1218   char result_exponent = 15;
1219   char result_mantissa = 64;
1220 #else
1221   char result_exponent = 11;
1222   char result_mantissa = 52;
1223 #endif
1224
1225   temp = alloca(calc_buffer_size);
1226 #ifdef HAVE_EXPLICIT_ONE
1227   value = fc_cast(val, result_exponent, result_mantissa-1, temp);
1228 #else
1229   value = fc_cast(val, result_exponent, result_mantissa, temp);
1230 #endif
1231
1232   sign = _sign(value);
1233
1234   /* @@@ long double exponent is 15bit, so the use of sc_val_to_long should not
1235    * lead to wrong results */
1236   exponent = sc_val_to_long(_exp(value)) ;
1237
1238   sc_val_from_ulong(2, NULL);
1239   _shift_right(_mant(value), sc_get_buffer(), _mant(value));
1240
1241   mantissa0 = 0;
1242   mantissa1 = 0;
1243
1244   for (byte_offset = 0; byte_offset < 4; byte_offset++)
1245     mantissa1 |= sc_sub_bits(_mant(value), result_mantissa, byte_offset) << (byte_offset<<3);
1246
1247   for (; (byte_offset<<3) < result_mantissa; byte_offset++)
1248     mantissa0 |= sc_sub_bits(_mant(value), result_mantissa, byte_offset) << ((byte_offset-4)<<3);
1249
1250 #ifdef HAVE_LONG_DOUBLE
1251   buildval.val.high = sign << 15;
1252   buildval.val.high |= exponent;
1253   buildval.val.mid = mantissa0;
1254   buildval.val.low = mantissa1;
1255 #else /* no long double */
1256   mantissa0 &= 0x000FFFFF;  /* get rid of garbage */
1257   buildval.val.high = sign << 31;
1258   buildval.val.high |= exponent << 20;
1259   buildval.val.high |= mantissa0;
1260   buildval.val.low = mantissa1;
1261 #endif
1262
1263   TRACEPRINTF(("val_to_float: %d-%x-%x%x\n", sign, exponent, mantissa0, mantissa1));
1264   return buildval.d;
1265 }
1266
1267 char* fc_cast(const void *val, char exp_size, char mant_size, char *result)
1268 {
1269   const char *value = (const char*) val;
1270   char *temp;
1271   int exp_offset, val_bias, res_bias;
1272
1273   if (result == NULL) result = calc_buffer;
1274   temp = alloca(value_size);
1275
1276   if (_desc(value).exponent_size == exp_size && _desc(value).mantissa_size == mant_size)
1277   {
1278     if (value != result) memcpy(result, value, calc_buffer_size);
1279     return result;
1280   }
1281
1282   /* set the descriptor of the new value */
1283   _desc(result).exponent_size = exp_size;
1284   _desc(result).mantissa_size = mant_size;
1285   _desc(result).clss = _desc(value).clss;
1286
1287   _sign(result) = _sign(value);
1288
1289   /* when the mantissa sizes differ normalizing has to shift to align it.
1290    * this would change the exponent, which is unwanted. So calculate this
1291    * offset and add it */
1292   val_bias = (1<<_desc(value).exponent_size)/2-1;
1293   res_bias = (1<<exp_size)/2-1;
1294
1295   exp_offset = (res_bias - val_bias) - (_desc(value).mantissa_size - mant_size);
1296   sc_val_from_long(exp_offset, temp);
1297   sc_add(_exp(value), temp, _exp(result));
1298
1299   /* _normalize expects normalized radix point */
1300   if (_desc(val).clss == SUBNORMAL) {
1301     sc_val_from_ulong(1, NULL);
1302     _shift_left(_mant(val), sc_get_buffer(), _mant(result));
1303   } else if (value != result) {
1304     memcpy(_mant(result), _mant(value), value_size);
1305   } else {
1306     memmove(_mant(result), _mant(value), value_size);
1307   }
1308
1309   _normalize(result, result, 0);
1310   TRACEPRINTF(("Cast results in %s\n", fc_print(result, temp, value_size, FC_PACKED)));
1311   return result;
1312 }
1313
1314 char* fc_get_max(unsigned int exponent_size, unsigned int mantissa_size, char* result)
1315 {
1316   if (result == NULL) result = calc_buffer;
1317
1318   _desc(result).exponent_size = exponent_size;
1319   _desc(result).mantissa_size = mantissa_size;
1320   _desc(result).clss = NORMAL;
1321
1322   _sign(result) = 0;
1323
1324   sc_val_from_ulong((1<<exponent_size) - 2, _exp(result));
1325
1326   sc_max_from_bits(mantissa_size + 1, 0, _mant(result));
1327   sc_val_from_ulong(2, NULL);
1328   _shift_left(_mant(result), sc_get_buffer(), _mant(result));
1329
1330   return result;
1331 }
1332
1333 char* fc_get_min(unsigned int exponent_size, unsigned int mantissa_size, char *result)
1334 {
1335   if (result == NULL) result = calc_buffer;
1336
1337   fc_get_max(exponent_size, mantissa_size, result);
1338   _sign(result) = 1;
1339
1340   return result;
1341 }
1342
1343 char* fc_get_snan(unsigned int exponent_size, unsigned int mantissa_size, char *result)
1344 {
1345   if (result == NULL) result = calc_buffer;
1346
1347   _desc(result).exponent_size = exponent_size;
1348   _desc(result).mantissa_size = mantissa_size;
1349   _desc(result).clss = NAN;
1350
1351   _sign(result) = 0;
1352
1353   sc_val_from_ulong((1<<exponent_size)-1, _exp(result));
1354
1355   /* signaling NaN has non-zero mantissa with msb not set */
1356   sc_val_from_ulong(1, _mant(result));
1357
1358   return result;
1359 }
1360
1361 char* fc_get_qnan(unsigned int exponent_size, unsigned int mantissa_size, char *result)
1362 {
1363   if (result == NULL) result = calc_buffer;
1364
1365   _desc(result).exponent_size = exponent_size;
1366   _desc(result).mantissa_size = mantissa_size;
1367   _desc(result).clss = NAN;
1368
1369   _sign(result) = 0;
1370
1371   sc_val_from_ulong((1<<exponent_size)-1, _exp(result));
1372
1373   /* quiet NaN has the msb of the mantissa set, so shift one there */
1374   sc_val_from_ulong(1, _mant(result));
1375   /* mantissa_size >+< 1 because of two extra rounding bits */
1376   sc_val_from_ulong(mantissa_size + 1, NULL);
1377   _shift_left(_mant(result), sc_get_buffer(), _mant(result));
1378
1379   return result;
1380 }
1381
1382 char* fc_get_plusinf(unsigned int exponent_size, unsigned int mantissa_size, char *result)
1383 {
1384   if (result == NULL) result = calc_buffer;
1385
1386   _desc(result).exponent_size = exponent_size;
1387   _desc(result).mantissa_size = mantissa_size;
1388   _desc(result).clss = NORMAL;
1389
1390   _sign(result) = 0;
1391
1392   sc_val_from_ulong((1<<exponent_size)-1, _exp(result));
1393
1394   sc_val_from_ulong(0, _mant(result));
1395
1396   return result;
1397 }
1398
1399 char* fc_get_minusinf(unsigned int exponent_size, unsigned int mantissa_size, char *result)
1400 {
1401   if (result == NULL) result = calc_buffer;
1402
1403   fc_get_plusinf(exponent_size, mantissa_size, result);
1404   _sign(result) = 1;
1405
1406   return result;
1407 }
1408
1409 int fc_comp(const void *a, const void *b)
1410 {
1411   const char *val_a = (const char*)a;
1412   const char *val_b = (const char*)b;
1413   int mul = 1;
1414
1415   /*
1416    * shortcut: if both values are identical, they are either
1417    * Unordered if NaN or equal
1418    */
1419   if (a == b)
1420     return _desc(val_a).clss == NAN ? 2 : 0;
1421
1422   /* unordered if one is a NaN */
1423   if (_desc(val_a).clss == NAN || _desc(val_b).clss == NAN)
1424     return 2;
1425
1426   /* zero is equal independent of sign */
1427   if ((_desc(val_a).clss == ZERO) && (_desc(val_b).clss == ZERO))
1428     return 0;
1429
1430   /* different signs make compare easy */
1431   if (_sign(val_a) != _sign(val_b))
1432     return (_sign(val_a)==0)?(1):(-1);
1433
1434   mul = _sign(a) ? -1 : 1;
1435
1436   /* both infinity means equality */
1437   if ((_desc(val_a).clss == INF) && (_desc(val_b).clss == INF))
1438     return 0;
1439
1440   /* infinity is bigger than the rest */
1441   if (_desc(val_a).clss == INF)
1442     return  1 * mul;
1443   if (_desc(val_b).clss == INF)
1444     return -1 * mul;
1445
1446   /* check first exponent, that mantissa if equal */
1447   switch (sc_comp(_exp(val_a), _exp(val_b))) {
1448     case -1:
1449       return -1 * mul;
1450     case  1:
1451       return  1 * mul;
1452     case  0:
1453       return sc_comp(_mant(val_a), _mant(val_b)) * mul;
1454     default:
1455       return 2;
1456   }
1457 }
1458
1459 int fc_is_zero(const void *a)
1460 {
1461   return _desc(a).clss == ZERO;
1462 }
1463
1464 int fc_is_negative(const void *a)
1465 {
1466   return _sign(a);
1467 }
1468
1469 int fc_is_inf(const void *a)
1470 {
1471   return _desc(a).clss == INF;
1472 }
1473
1474 int fc_is_nan(const void *a)
1475 {
1476   return _desc(a).clss == NAN;
1477 }
1478
1479 int fc_is_subnormal(const void *a)
1480 {
1481   return _desc(a).clss == SUBNORMAL;
1482 }
1483
1484 char *fc_print(const void *a, char *buf, int buflen, unsigned base)
1485 {
1486   const char *val;
1487   char *mul_1;
1488
1489   val = (const char*)a;
1490
1491   mul_1 = alloca(calc_buffer_size);
1492
1493   switch (base) {
1494     case FC_DEC:
1495       switch (_desc(val).clss) {
1496         case INF:
1497           if (buflen >= 8+_sign(val)) sprintf(buf, "%sINFINITY", _sign(val)?"-":"");
1498           else snprintf(buf, buflen, "%sINF", _sign(val)?"-":NULL);
1499           break;
1500         case NAN:
1501           snprintf(buf, buflen, "NAN");
1502           break;
1503         case ZERO:
1504           snprintf(buf, buflen, "0.0");
1505           break;
1506         default:
1507           /* XXX to be implemented */
1508 #ifdef HAVE_LONG_DOUBLE
1509           /* XXX 30 is arbitrary */
1510           snprintf(buf, buflen, "%.30LE", fc_val_to_float(val));
1511 #else
1512           snprintf(buf, buflen, "%.18E", fc_val_to_float(val));
1513 #endif
1514       }
1515       break;
1516
1517     case FC_HEX:
1518       switch (_desc(val).clss) {
1519         case INF:
1520           if (buflen >= 8+_sign(val)) sprintf(buf, "%sINFINITY", _sign(val)?"-":"");
1521           else snprintf(buf, buflen, "%sINF", _sign(val)?"-":NULL);
1522           break;
1523         case NAN:
1524           snprintf(buf, buflen, "NAN");
1525           break;
1526         case ZERO:
1527           snprintf(buf, buflen, "0.0");
1528           break;
1529         default:
1530 #ifdef HAVE_LONG_DOUBLE
1531           snprintf(buf, buflen, "%LA", fc_val_to_float(val));
1532 #else
1533           snprintf(buf, buflen, "%A", fc_val_to_float(val));
1534 #endif
1535       }
1536       break;
1537
1538     case FC_PACKED:
1539     default:
1540       snprintf(buf, buflen, "%s", sc_print(_pack(val, mul_1), value_size*4, SC_HEX, 0));
1541       buf[buflen - 1] = '\0';
1542       break;
1543   }
1544   return buf;
1545 }
1546
1547 unsigned char fc_sub_bits(const void *value, unsigned num_bits, unsigned byte_ofs)
1548 {
1549   /* this is used to cache the packed version of the value */
1550   static char *pack = NULL;
1551
1552   if (pack == NULL) pack = xmalloc(value_size);
1553
1554   if (value != NULL)
1555     _pack((const char*)value, pack);
1556
1557   return sc_sub_bits(pack, num_bits, byte_ofs);
1558 }
1559
1560 fc_rounding_mode_t fc_set_rounding_mode(fc_rounding_mode_t mode)
1561 {
1562   if (mode == FC_TONEAREST || mode == FC_TOPOSITIVE || mode == FC_TONEGATIVE || mode == FC_TOZERO)
1563       rounding_mode = mode;
1564
1565   return rounding_mode;
1566 }
1567
1568 fc_rounding_mode_t fc_get_rounding_mode(void)
1569 {
1570   return rounding_mode;
1571 }
1572
1573 void init_fltcalc(int precision)
1574 {
1575   if (calc_buffer == NULL) {
1576     /* does nothing if already init */
1577     if (precision == 0) precision = FC_DEFAULT_PRECISION;
1578
1579     init_strcalc(precision + 4);
1580
1581     /* needs additionally two bits to round, a bit as explicit 1., and one for
1582      * addition overflow */
1583     max_precision = sc_get_precision() - 4;
1584     if (max_precision < precision)
1585       printf("WARING: not enough precision available, using %d\n", max_precision);
1586
1587     rounding_mode    = FC_TONEAREST;
1588     value_size       = sc_get_buffer_length();
1589     SIGN_POS         = 0;
1590     EXPONENT_POS     = SIGN_POS + sizeof(char);
1591     MANTISSA_POS     = EXPONENT_POS + value_size;
1592     DESCRIPTOR_POS   = MANTISSA_POS + value_size;
1593     calc_buffer_size = DESCRIPTOR_POS + sizeof(descriptor_t);
1594
1595     calc_buffer = xmalloc(calc_buffer_size);
1596     memset(calc_buffer, 0, calc_buffer_size);
1597     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));
1598 #ifdef HAVE_LONG_DOUBLE
1599     DEBUGPRINTF(("\tUsing long double (1-15-64) interface\n"));
1600 #else
1601     DEBUGPRINTF(("\tUsing double (1-11-52) interface\n"));
1602 #endif
1603 #ifdef WORDS_BIGENDIAN
1604     DEBUGPRINTF(("\tWord order is big endian\n\n"));
1605 #else
1606     DEBUGPRINTF(("\tWord order is little endian\n\n"));
1607 #endif
1608   }
1609 }
1610
1611 void finish_fltcalc (void) {
1612   free(calc_buffer); calc_buffer = NULL;
1613 }
1614
1615 /* definition of interface functions */
1616 FC_DEFINE2(add)
1617 FC_DEFINE2(sub)
1618 FC_DEFINE2(mul)
1619 FC_DEFINE2(div)
1620 FC_DEFINE1(neg)
1621 FC_DEFINE1(int)
1622 FC_DEFINE1(rnd)