- fixed warning
[libfirm] / ir / tv / fltcalc.c
index 5e2fc0a..0f162da 100644 (file)
@@ -25,9 +25,7 @@
  * @version  $Id$
  */
 
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
+#include "config.h"
 
 #include "fltcalc.h"
 #include "strcalc.h"
 #ifdef HAVE_INTTYPES_H
 # include <inttypes.h>
 #endif
-#ifdef HAVE_STRING_H
-# include <string.h>
-#endif
-#ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-#endif
+#include <string.h>
+#include <stdlib.h>
 #include <stdio.h>
 #include <assert.h>
 
@@ -182,6 +176,8 @@ static void *pack(const fp_value *int_float, void *packed) {
        default:
                break;
        }
+       assert(int_float->desc.explicit_one <= 1);
+
        /* pack sign: move it to the left after exponent AND mantissa */
        sc_val_from_ulong(int_float->sign, temp);
 
@@ -397,16 +393,19 @@ static int normalize(const fp_value *in_val, fp_value *out_val, int sticky) {
 }
 
 /**
- * Operations involving NaN's must return NaN
+ * Operations involving NaN's must return NaN.
+ * They are NOT exact.
  */
 #define handle_NAN(a, b, result) \
 do {                                                      \
   if (a->desc.clss == NAN) {                              \
     if (a != result) memcpy(result, a, calc_buffer_size); \
+    fc_exact = 0;                                         \
     return;                                               \
   }                                                       \
   if (b->desc.clss == NAN) {                              \
     if (b != result) memcpy(result, b, calc_buffer_size); \
+    fc_exact = 0;                                         \
     return;                                               \
   }                                                       \
 }while (0)
@@ -435,6 +434,7 @@ static void _fadd(const fp_value *a, const fp_value *b, fp_value *result) {
 
        /* produce NaN on inf - inf */
        if (sign && (a->desc.clss == INF) && (b->desc.clss == INF)) {
+               fc_exact = 0;
                fc_get_qnan(&a->desc, result);
                return;
        }
@@ -474,12 +474,14 @@ static void _fadd(const fp_value *a, const fp_value *b, fp_value *result) {
        if (a->desc.clss == ZERO || b->desc.clss == INF) {
                if (b != result)
                        memcpy(result, b, calc_buffer_size);
+               fc_exact = b->desc.clss == NORMAL;
                result->sign = res_sign;
                return;
        }
        if (b->desc.clss == ZERO || a->desc.clss == INF) {
                if (a != result)
                        memcpy(result, a, calc_buffer_size);
+               fc_exact = a->desc.clss == NORMAL;
                result->sign = res_sign;
                return;
        }
@@ -548,9 +550,10 @@ static void _fmul(const fp_value *a, const fp_value *b, fp_value *result) {
 
        /* produce NaN on 0 * inf */
        if (a->desc.clss == ZERO) {
-               if (b->desc.clss == INF)
+               if (b->desc.clss == INF) {
                        fc_get_qnan(&a->desc, result);
-               else {
+                       fc_exact = 0;
+               } else {
                        if (a != result)
                                memcpy(result, a, calc_buffer_size);
                        result->sign = res_sign;
@@ -558,9 +561,10 @@ static void _fmul(const fp_value *a, const fp_value *b, fp_value *result) {
                return;
        }
        if (b->desc.clss == ZERO) {
-               if (a->desc.clss == INF)
+               if (a->desc.clss == INF) {
                        fc_get_qnan(&a->desc, result);
-               else {
+                       fc_exact = 0;
+               } else {
                        if (b != result)
                                memcpy(result, b, calc_buffer_size);
                        result->sign = res_sign;
@@ -569,12 +573,14 @@ static void _fmul(const fp_value *a, const fp_value *b, fp_value *result) {
        }
 
        if (a->desc.clss == INF) {
+               fc_exact = 0;
                if (a != result)
                        memcpy(result, a, calc_buffer_size);
                result->sign = res_sign;
                return;
        }
        if (b->desc.clss == INF) {
+               fc_exact = 0;
                if (b != result)
                        memcpy(result, b, calc_buffer_size);
                result->sign = res_sign;
@@ -631,10 +637,11 @@ static void _fdiv(const fp_value *a, const fp_value *b, fp_value *result) {
 
        /* produce NAN on 0/0 and inf/inf */
        if (a->desc.clss == ZERO) {
-               if (b->desc.clss == ZERO)
+               if (b->desc.clss == ZERO) {
                        /* 0/0 -> NaN */
                        fc_get_qnan(&a->desc, result);
-               else {
+                       fc_exact = 0;
+               } else {
                        /* 0/x -> a */
                        if (a != result)
                                memcpy(result, a, calc_buffer_size);
@@ -644,10 +651,11 @@ static void _fdiv(const fp_value *a, const fp_value *b, fp_value *result) {
        }
 
        if (b->desc.clss == INF) {
-               if (a->desc.clss == INF)
+               fc_exact = 0;
+               if (a->desc.clss == INF) {
                        /* inf/inf -> NaN */
                        fc_get_qnan(&a->desc, result);
-               else {
+               else {
                        /* x/inf -> 0 */
                        sc_val_from_ulong(0, NULL);
                        _save_result(_exp(result));
@@ -658,6 +666,7 @@ static void _fdiv(const fp_value *a, const fp_value *b, fp_value *result) {
        }
 
        if (a->desc.clss == INF) {
+               fc_exact = 0;
                /* inf/x -> inf */
                if (a != result)
                        memcpy(result, a, calc_buffer_size);
@@ -665,6 +674,7 @@ static void _fdiv(const fp_value *a, const fp_value *b, fp_value *result) {
                return;
        }
        if (b->desc.clss == ZERO) {
+               fc_exact = 0;
                /* division by zero */
                if (result->sign)
                        fc_get_minusinf(&a->desc, result);
@@ -1024,10 +1034,11 @@ done:
 }
 
 fp_value *fc_val_from_ieee754(LLDBL l, const ieee_descriptor_t *desc, fp_value *result) {
-       char *temp;
-       int bias_res, bias_val, mant_val;
+       char    *temp;
+       int     bias_res, bias_val, mant_val;
        value_t srcval;
-       UINT32 sign, exponent, mantissa0, mantissa1;
+       char    sign;
+       UINT32  exponent, mantissa0, mantissa1;
 
        srcval.d = l;
        bias_res = ((1 << (desc->exponent_size - 1)) - 1);
@@ -1321,7 +1332,7 @@ fp_value *fc_get_plusinf(const ieee_descriptor_t *desc, fp_value *result) {
        result->desc.exponent_size = desc->exponent_size;
        result->desc.mantissa_size = desc->mantissa_size;
        result->desc.explicit_one  = desc->explicit_one;
-       result->desc.clss          = NORMAL;
+       result->desc.clss          = INF;
 
        result->sign = 0;
 
@@ -1418,11 +1429,10 @@ char *fc_print(const fp_value *val, char *buf, int buflen, unsigned base) {
        case FC_DEC:
                switch ((value_class_t)val->desc.clss) {
                case INF:
-                       if (buflen >= 8 + val->sign) sprintf(buf, "%sINFINITY", val->sign ? "-":"");
-                       else snprintf(buf, buflen, "%sINF", val->sign ? "-":NULL);
+                       snprintf(buf, buflen, "%cINF", val->sign ? '-' : '+');
                        break;
                case NAN:
-                       snprintf(buf, buflen, "NAN");
+                       snprintf(buf, buflen, "NaN");
                        break;
                case ZERO:
                        snprintf(buf, buflen, "0.0");
@@ -1441,8 +1451,7 @@ char *fc_print(const fp_value *val, char *buf, int buflen, unsigned base) {
        case FC_HEX:
                switch ((value_class_t)val->desc.clss) {
                case INF:
-                       if (buflen >= 8+val->sign) sprintf(buf, "%sINFINITY", val->sign?"-":"");
-                       else snprintf(buf, buflen, "%sINF", val->sign?"-":NULL);
+                       snprintf(buf, buflen, "%cINF", val->sign ? '-' : '+');
                        break;
                case NAN:
                        snprintf(buf, buflen, "NAN");
@@ -1473,7 +1482,7 @@ unsigned char fc_sub_bits(const fp_value *value, unsigned num_bits, unsigned byt
        /* this is used to cache the packed version of the value */
        static char *packed_value = NULL;
 
-       if (packed_value == NULL) packed_value = xmalloc(value_size);
+       if (packed_value == NULL) packed_value = XMALLOCN(char, value_size);
 
        if (value != NULL)
                pack(value, packed_value);