Cygwin has no strtold but long double works
[libfirm] / ir / tv / fltcalc.c
index d1ba43f..973faf7 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>
 
@@ -817,7 +811,10 @@ static void _trunc(const fp_value *a, fp_value *result) {
        /* and the mask and return the result */
        sc_and(_mant(a), temp, _mant(result));
 
-       if (a != result) memcpy(_exp(result), _exp(a), value_size);
+       if (a != result) {
+               memcpy(_exp(result), _exp(a), value_size);
+               result->sign = a->sign;
+       }
 }
 
 /********
@@ -1018,7 +1015,7 @@ done:
        ieee_descriptor_t tmp_desc;
        (void) len;
 
-#ifdef HAVE_LONG_DOUBLE
+#if defined(HAVE_LONG_DOUBLE) && !defined(__CYGWIN__)
        val = strtold(str, NULL);
        DEBUGPRINTF(("val_from_str(%s)\n", str));
        tmp_desc.exponent_size = 15;
@@ -1040,10 +1037,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);
@@ -1487,7 +1485,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);
@@ -1692,6 +1690,7 @@ int fc_flt2int(const fp_value *a, void *result, ir_mode *dst_mode) {
                int exp_bias = (1 << (a->desc.exponent_size - 1)) - 1;
                int exp_val  = sc_val_to_long(_exp(a)) - exp_bias;
                int shift, highest;
+               int mantissa_size;
 
                if (a->sign && !mode_is_signed(dst_mode)) {
                        /* FIXME: for now we cannot convert this */
@@ -1699,12 +1698,14 @@ int fc_flt2int(const fp_value *a, void *result, ir_mode *dst_mode) {
                }
 
                assert(exp_val >= 0 && "floating point value not integral before fc_flt2int() call");
-               shift = exp_val - (a->desc.mantissa_size + ROUNDING_BITS);
+               mantissa_size = a->desc.mantissa_size + ROUNDING_BITS;
+               shift         = exp_val - mantissa_size;
 
+               mantissa_size += a->desc.explicit_one;
                if (shift > 0) {
-                       sc_shlI(_mant(a),  shift, 64, 0, result);
+                       sc_shlI(_mant(a),  shift, mantissa_size, 0, result);
                } else {
-                       sc_shrI(_mant(a), -shift, 64, 0, result);
+                       sc_shrI(_mant(a), -shift, mantissa_size, 0, result);
                }
 
                /* check for overflow */