beinsn: Do not store, whether an insn has constraints.
[libfirm] / ir / tv / fltcalc.c
index 2858449..1c6512c 100644 (file)
@@ -22,7 +22,6 @@
  * @brief    tarval floating point calculations
  * @date     2003
  * @author   Mathias Heil
- * @version  $Id$
  */
 #include "config.h"
 
 #include "error.h"
 
 #include <math.h>
-/* undef some reused constants defined by math.h */
-#ifdef NAN
-#  undef NAN
-#endif
-
 #include <inttypes.h>
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <assert.h>
+#include <stdbool.h>
 
 #include "xmalloc.h"
 
-#ifdef _MSC_VER
-#include <float.h>
-#define isnan(x)   _isnan(x)
-static inline int isinf(double x)
+/*
+ * portability stuff (why do we even care about the msvc people with their C89?)
+ */
+
+
+static long double string_to_long_double(const char *str)
 {
-       return !_finite(x) && !_isnan(x);
+#if __STDC_VERSION__ >= 199901L || _POSIX_C_SOURCE >= 200112L
+       return strtold(str, NULL);
+#else
+       return strtod(str, NULL);
+#endif
 }
-#define strtold(s, e) strtod(s, e)
-#define SIZEOF_LONG_DOUBLE_8
+
+static bool my_isnan(long double val)
+{
+#if __STDC_VERSION__ >= 199901L
+       return isnan(val);
+#else
+       /* hopefully the compiler does not optimize aggressively (=incorrect) */
+       return val != val;
+#endif
+}
+
+static bool my_isinf(long double val)
+{
+#if __STDC_VERSION__ >= 199901L
+       return isinf(val);
+#else
+       /* hopefully the compiler does not optimize aggressively (=incorrect) */
+       return my_isnan(val-val) && !my_isnan(val);
 #endif
+}
 
 /** The number of extra precision rounding bits */
 #define ROUNDING_BITS 2
@@ -65,15 +83,25 @@ typedef union {
 #else
                uint32_t low;
 #endif
-#ifndef SIZEOF_LONG_DOUBLE_8
                uint32_t mid;
+#ifdef WORDS_BIGENDIAN
+               uint32_t low;
+#else
+               uint32_t high;
+#endif
+       } val_ld12;
+       struct {
+#ifdef WORDS_BIGENDIAN
+               uint32_t high;
+#else
+               uint32_t low;
 #endif
 #ifdef WORDS_BIGENDIAN
                uint32_t low;
 #else
                uint32_t high;
 #endif
-       } val;
+       } val_ld8;
        volatile long double d;
 } value_t;
 
@@ -81,7 +109,8 @@ typedef union {
 
 /* our floating point value */
 struct fp_value {
-       ieee_descriptor_t desc;
+       float_descriptor_t desc;
+       unsigned char clss;
        char sign;
        char value[1];        /* exp[value_size] + mant[value_size] */
 };
@@ -106,9 +135,6 @@ struct fp_value {
 #  define TRACEPRINTF(x) ((void)0)
 #endif
 
-/** The immediate precision. */
-static unsigned immediate_prec = 0;
-
 /** A temporal buffer. */
 static fp_value *calc_buffer = NULL;
 
@@ -133,14 +159,14 @@ static void *pack(const fp_value *int_float, void *packed)
        temp      = (char*) alloca(value_size);
        shift_val = (char*) alloca(value_size);
 
-       switch ((value_class_t)int_float->desc.clss) {
-       case NAN:
+       switch ((value_class_t)int_float->clss) {
+       case FC_NAN:
                val_buffer = (fp_value*) alloca(calc_buffer_size);
                fc_get_qnan(&int_float->desc, val_buffer);
                int_float = val_buffer;
                break;
 
-       case INF:
+       case FC_INF:
                val_buffer = (fp_value*) alloca(calc_buffer_size);
                fc_get_plusinf(&int_float->desc, val_buffer);
                val_buffer->sign = int_float->sign;
@@ -202,7 +228,7 @@ static int normalize(const fp_value *in_val, fp_value *out_val, int sticky)
                out_val->desc = in_val->desc;
        }
 
-       out_val->desc.clss = NORMAL;
+       out_val->clss = FC_NORMAL;
 
        /* mantissa all zeros, so zero exponent (because of explicit one) */
        if (hsb == ROUNDING_BITS + in_val->desc.mantissa_size)   {
@@ -248,7 +274,7 @@ static int normalize(const fp_value *in_val, fp_value *out_val, int sticky)
                /* denormalized means exponent of zero */
                sc_val_from_ulong(0, _exp(out_val));
 
-               out_val->desc.clss = SUBNORMAL;
+               out_val->clss = FC_SUBNORMAL;
        }
 
        /* perform rounding by adding a value that clears the guard bit and the round bit
@@ -294,24 +320,24 @@ static int normalize(const fp_value *in_val, fp_value *out_val, int sticky)
        }
 
        /* could have rounded down to zero */
-       if (sc_is_zero(_mant(out_val)) && (out_val->desc.clss == SUBNORMAL))
-               out_val->desc.clss = ZERO;
+       if (sc_is_zero(_mant(out_val)) && (out_val->clss == FC_SUBNORMAL))
+               out_val->clss = FC_ZERO;
 
        /* check for rounding overflow */
        hsb = ROUNDING_BITS + out_val->desc.mantissa_size - sc_get_highest_set_bit(_mant(out_val)) - 1;
-       if ((out_val->desc.clss != SUBNORMAL) && (hsb < -1)) {
+       if ((out_val->clss != FC_SUBNORMAL) && (hsb < -1)) {
                sc_val_from_ulong(1, temp);
                _shift_right(_mant(out_val), temp, _mant(out_val));
                if (exact && sc_had_carry())
                        exact = 0;
                sc_add(_exp(out_val), temp, _exp(out_val));
-       } else if ((out_val->desc.clss == SUBNORMAL) && (hsb == -1)) {
+       } else if ((out_val->clss == FC_SUBNORMAL) && (hsb == -1)) {
                /* overflow caused the mantissa to be normal again,
                 * so adapt the exponent accordingly */
                sc_val_from_ulong(1, temp);
                sc_add(_exp(out_val), temp, _exp(out_val));
 
-               out_val->desc.clss = NORMAL;
+               out_val->clss = FC_NORMAL;
        }
        /* no further rounding is needed, because rounding overflow means
         * the carry of the original rounding was propagated all the way
@@ -343,7 +369,7 @@ static int normalize(const fp_value *in_val, fp_value *out_val, int sticky)
                        switch (rounding_mode) {
                        case FC_TONEAREST:
                        case FC_TOPOSITIVE:
-                               out_val->desc.clss = INF;
+                               out_val->clss = FC_INF;
                                break;
 
                        case FC_TONEGATIVE:
@@ -355,7 +381,7 @@ static int normalize(const fp_value *in_val, fp_value *out_val, int sticky)
                        switch (rounding_mode) {
                        case FC_TONEAREST:
                        case FC_TONEGATIVE:
-                               out_val->desc.clss = INF;
+                               out_val->clss = FC_INF;
                                break;
 
                        case FC_TOPOSITIVE:
@@ -373,12 +399,12 @@ static int normalize(const fp_value *in_val, fp_value *out_val, int sticky)
  */
 #define handle_NAN(a, b, result) \
 do {                                                      \
-  if (a->desc.clss == NAN) {                              \
+  if (a->clss == FC_NAN) {                                \
     if (a != result) memcpy(result, a, calc_buffer_size); \
     fc_exact = 0;                                         \
     return;                                               \
   }                                                       \
-  if (b->desc.clss == NAN) {                              \
+  if (b->clss == FC_NAN) {                                \
     if (b != result) memcpy(result, b, calc_buffer_size); \
     fc_exact = 0;                                         \
     return;                                               \
@@ -409,7 +435,7 @@ static void _fadd(const fp_value *a, const fp_value *b, fp_value *result)
        sign = a->sign ^ b->sign;
 
        /* produce NaN on inf - inf */
-       if (sign && (a->desc.clss == INF) && (b->desc.clss == INF)) {
+       if (sign && (a->clss == FC_INF) && (b->clss == FC_INF)) {
                fc_exact = 0;
                fc_get_qnan(&a->desc, result);
                return;
@@ -447,17 +473,17 @@ static void _fadd(const fp_value *a, const fp_value *b, fp_value *result)
        result->sign = res_sign;
 
        /* sign has been taken care of, check for special cases */
-       if (a->desc.clss == ZERO || b->desc.clss == INF) {
+       if (a->clss == FC_ZERO || b->clss == FC_INF) {
                if (b != result)
                        memcpy(result, b, calc_buffer_size);
-               fc_exact = b->desc.clss == NORMAL;
+               fc_exact = b->clss == FC_NORMAL;
                result->sign = res_sign;
                return;
        }
-       if (b->desc.clss == ZERO || a->desc.clss == INF) {
+       if (b->clss == FC_ZERO || a->clss == FC_INF) {
                if (a != result)
                        memcpy(result, a, calc_buffer_size);
-               fc_exact = a->desc.clss == NORMAL;
+               fc_exact = a->clss == FC_NORMAL;
                result->sign = res_sign;
                return;
        }
@@ -465,7 +491,7 @@ static void _fadd(const fp_value *a, const fp_value *b, fp_value *result)
        /* shift the smaller value to the right to align the radix point */
        /* subnormals have their radix point shifted to the right,
         * take care of this first */
-       if ((b->desc.clss == SUBNORMAL) && (a->desc.clss != SUBNORMAL)) {
+       if ((b->clss == FC_SUBNORMAL) && (a->clss != FC_SUBNORMAL)) {
                sc_val_from_ulong(1, temp);
                sc_sub(exp_diff, temp, exp_diff);
        }
@@ -494,7 +520,7 @@ static void _fadd(const fp_value *a, const fp_value *b, fp_value *result)
 
        /* _normalize expects a 'normal' radix point, adding two subnormals
         * results in a subnormal radix point -> shifting before normalizing */
-       if ((a->desc.clss == SUBNORMAL) && (b->desc.clss == SUBNORMAL)) {
+       if ((a->clss == FC_SUBNORMAL) && (b->clss == FC_SUBNORMAL)) {
                sc_val_from_ulong(1, NULL);
                _shift_left(_mant(result), sc_get_buffer(), _mant(result));
        }
@@ -526,8 +552,8 @@ static void _fmul(const fp_value *a, const fp_value *b, fp_value *result)
        result->sign = res_sign = a->sign ^ b->sign;
 
        /* produce NaN on 0 * inf */
-       if (a->desc.clss == ZERO) {
-               if (b->desc.clss == INF) {
+       if (a->clss == FC_ZERO) {
+               if (b->clss == FC_INF) {
                        fc_get_qnan(&a->desc, result);
                        fc_exact = 0;
                } else {
@@ -537,8 +563,8 @@ 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 (b->clss == FC_ZERO) {
+               if (a->clss == FC_INF) {
                        fc_get_qnan(&a->desc, result);
                        fc_exact = 0;
                } else {
@@ -549,14 +575,14 @@ static void _fmul(const fp_value *a, const fp_value *b, fp_value *result)
                return;
        }
 
-       if (a->desc.clss == INF) {
+       if (a->clss == FC_INF) {
                fc_exact = 0;
                if (a != result)
                        memcpy(result, a, calc_buffer_size);
                result->sign = res_sign;
                return;
        }
-       if (b->desc.clss == INF) {
+       if (b->clss == FC_INF) {
                fc_exact = 0;
                if (b != result)
                        memcpy(result, b, calc_buffer_size);
@@ -571,7 +597,7 @@ static void _fmul(const fp_value *a, const fp_value *b, fp_value *result)
        sc_sub(_exp(result), temp, _exp(result));
 
        /* mixed normal, subnormal values introduce an error of 1, correct it */
-       if ((a->desc.clss == SUBNORMAL) ^ (b->desc.clss == SUBNORMAL)) {
+       if ((a->clss == FC_SUBNORMAL) ^ (b->clss == FC_SUBNORMAL)) {
                sc_val_from_ulong(1, temp);
                sc_add(_exp(result), temp, _exp(result));
        }
@@ -613,9 +639,9 @@ static void _fdiv(const fp_value *a, const fp_value *b, fp_value *result)
 
        result->sign = res_sign = a->sign ^ b->sign;
 
-       /* produce NAN on 0/0 and inf/inf */
-       if (a->desc.clss == ZERO) {
-               if (b->desc.clss == ZERO) {
+       /* produce FC_NAN on 0/0 and inf/inf */
+       if (a->clss == FC_ZERO) {
+               if (b->clss == FC_ZERO) {
                        /* 0/0 -> NaN */
                        fc_get_qnan(&a->desc, result);
                        fc_exact = 0;
@@ -628,9 +654,9 @@ static void _fdiv(const fp_value *a, const fp_value *b, fp_value *result)
                return;
        }
 
-       if (b->desc.clss == INF) {
+       if (b->clss == FC_INF) {
                fc_exact = 0;
-               if (a->desc.clss == INF) {
+               if (a->clss == FC_INF) {
                        /* inf/inf -> NaN */
                        fc_get_qnan(&a->desc, result);
                } else {
@@ -638,12 +664,12 @@ static void _fdiv(const fp_value *a, const fp_value *b, fp_value *result)
                        sc_val_from_ulong(0, NULL);
                        _save_result(_exp(result));
                        _save_result(_mant(result));
-                       result->desc.clss = ZERO;
+                       result->clss = FC_ZERO;
                }
                return;
        }
 
-       if (a->desc.clss == INF) {
+       if (a->clss == FC_INF) {
                fc_exact = 0;
                /* inf/x -> inf */
                if (a != result)
@@ -651,7 +677,7 @@ static void _fdiv(const fp_value *a, const fp_value *b, fp_value *result)
                result->sign = res_sign;
                return;
        }
-       if (b->desc.clss == ZERO) {
+       if (b->clss == FC_ZERO) {
                fc_exact = 0;
                /* division by zero */
                if (result->sign)
@@ -667,7 +693,7 @@ static void _fdiv(const fp_value *a, const fp_value *b, fp_value *result)
        sc_add(_exp(result), temp, _exp(result));
 
        /* mixed normal, subnormal values introduce an error of 1, correct it */
-       if ((a->desc.clss == SUBNORMAL) ^ (b->desc.clss == SUBNORMAL)) {
+       if ((a->clss == FC_SUBNORMAL) ^ (b->clss == FC_SUBNORMAL)) {
                sc_val_from_ulong(1, temp);
                sc_add(_exp(result), temp, _exp(result));
        }
@@ -695,7 +721,7 @@ static void _fdiv(const fp_value *a, const fp_value *b, fp_value *result)
 }
 
 #if 0
-static void _power_of_ten(int exp, ieee_descriptor_t *desc, char *result)
+static void _power_of_ten(int exp, float_descriptor_t *desc, char *result)
 {
        char *build;
        char *temp;
@@ -760,8 +786,10 @@ static void _trunc(const fp_value *a, fp_value *result)
 
        temp = (char*) alloca(value_size);
 
-       if (a != result)
+       if (a != result) {
                result->desc = a->desc;
+               result->clss = a->clss;
+       }
 
        exp_bias = (1 << (a->desc.exponent_size - 1)) - 1;
        exp_val  = sc_val_to_long(_exp(a)) - exp_bias;
@@ -770,7 +798,7 @@ static void _trunc(const fp_value *a, fp_value *result)
                sc_val_from_ulong(0, NULL);
                _save_result(_exp(result));
                _save_result(_mant(result));
-               result->desc.clss = ZERO;
+               result->clss = FC_ZERO;
 
                return;
        }
@@ -810,78 +838,80 @@ int fc_get_buffer_length(void)
        return calc_buffer_size;
 }
 
-void *fc_val_from_str(const char *str, size_t len, const ieee_descriptor_t *desc, void *result)
+void *fc_val_from_str(const char *str, size_t len,
+                      const float_descriptor_t *desc, void *result)
 {
        char *buffer;
 
        /* XXX excuse of an implementation to make things work */
        long double        val;
        fp_value          *tmp = (fp_value*) alloca(calc_buffer_size);
-       ieee_descriptor_t tmp_desc;
+       float_descriptor_t tmp_desc;
 
        buffer = (char*) alloca(len+1);
        memcpy(buffer, str, len);
        buffer[len] = '\0';
-       val = strtold(buffer, NULL);
+       val = string_to_long_double(buffer);
 
        DEBUGPRINTF(("val_from_str(%s)\n", str));
        tmp_desc.exponent_size = 15;
        tmp_desc.mantissa_size = 63;
        tmp_desc.explicit_one  = 1;
-       tmp_desc.clss          = NORMAL;
        fc_val_from_ieee754(val, &tmp_desc, tmp);
 
        return fc_cast(tmp, desc, (fp_value*) result);
 }
 
-fp_value *fc_val_from_ieee754(long double l, const ieee_descriptor_t *desc, fp_value *result)
+fp_value *fc_val_from_ieee754(long double l, const float_descriptor_t *desc,
+                              fp_value *result)
 {
        char    *temp;
        int      bias_res, bias_val, mant_val;
        value_t  srcval;
        char     sign;
        uint32_t exponent, mantissa0, mantissa1;
+       size_t   long_double_size = sizeof(long double);
 
        srcval.d = l;
        bias_res = ((1 << (desc->exponent_size - 1)) - 1);
 
-#ifdef SIZEOF_LONG_DOUBLE_8
-       mant_val  = 52;
-       bias_val  = 0x3ff;
-       sign      = (srcval.val.high & 0x80000000) != 0;
-       exponent  = (srcval.val.high & 0x7FF00000) >> 20;
-       mantissa0 = srcval.val.high & 0x000FFFFF;
-       mantissa1 = srcval.val.low;
-#else
-       mant_val  = 63;
-       bias_val  = 0x3fff;
-       sign      = (srcval.val.high & 0x00008000) != 0;
-       exponent  = (srcval.val.high & 0x00007FFF) ;
-       mantissa0 = srcval.val.mid;
-       mantissa1 = srcval.val.low;
-#endif
+       if (long_double_size == 8) {
+               mant_val  = 52;
+               bias_val  = 0x3ff;
+               sign      = (srcval.val_ld8.high & 0x80000000) != 0;
+               exponent  = (srcval.val_ld8.high & 0x7FF00000) >> 20;
+               mantissa0 = srcval.val_ld8.high & 0x000FFFFF;
+               mantissa1 = srcval.val_ld8.low;
+       } else {
+               /* we assume an x86-like 80bit representation of the value... */
+               assert(sizeof(long double)==12 || sizeof(long double)==16);
+               mant_val  = 63;
+               bias_val  = 0x3fff;
+               sign      = (srcval.val_ld12.high & 0x00008000) != 0;
+               exponent  = (srcval.val_ld12.high & 0x00007FFF) ;
+               mantissa0 = srcval.val_ld12.mid;
+               mantissa1 = srcval.val_ld12.low;
+       }
 
-       if (result == NULL) result = calc_buffer;
+       if (result == NULL)
+               result = calc_buffer;
        temp = (char*) alloca(value_size);
 
        /* CLEAR the buffer, else some bits might be uninitialized */
        memset(result, 0, fc_get_buffer_length());
 
-       result->desc.exponent_size = desc->exponent_size;
-       result->desc.mantissa_size = desc->mantissa_size;
-       result->desc.explicit_one  = desc->explicit_one;
-
-       /* extract sign */
+       result->desc = *desc;
+       result->clss = FC_NORMAL;
        result->sign = sign;
 
        /* sign and flag suffice to identify NaN or inf, no exponent/mantissa
         * encoding is needed. the function can return immediately in these cases */
-       if (isnan(l)) {
-               result->desc.clss = NAN;
+       if (my_isnan(l)) {
+               result->clss = FC_NAN;
                TRACEPRINTF(("val_from_float resulted in NAN\n"));
                return result;
-       } else if (isinf(l)) {
-               result->desc.clss = INF;
+       } else if (my_isinf(l)) {
+               result->clss = FC_INF;
                TRACEPRINTF(("val_from_float resulted in %sINF\n", (result->sign == 1) ? "-" : ""));
                return result;
        }
@@ -944,20 +974,20 @@ long double fc_val_to_ieee754(const fp_value *val)
        uint32_t mantissa1;
 
        value_t           buildval;
-       ieee_descriptor_t desc;
+       float_descriptor_t desc;
        unsigned          mantissa_size;
 
-#ifdef SIZEOF_LONG_DOUBLE_8
-       desc.exponent_size = 11;
-       desc.mantissa_size = 52;
-       desc.explicit_one  = 0;
-       desc.clss          = NORMAL;
-#else
-       desc.exponent_size = 15;
-       desc.mantissa_size = 63;
-       desc.explicit_one  = 1;
-       desc.clss          = NORMAL;
-#endif
+       size_t            long_double_size = sizeof(long double);
+
+       if (long_double_size == 8) {
+               desc.exponent_size = 11;
+               desc.mantissa_size = 52;
+               desc.explicit_one  = 0;
+       } else {
+               desc.exponent_size = 15;
+               desc.mantissa_size = 63;
+               desc.explicit_one  = 1;
+       }
        mantissa_size = desc.mantissa_size + desc.explicit_one;
 
        temp = (fp_value*) alloca(calc_buffer_size);
@@ -981,24 +1011,25 @@ long double fc_val_to_ieee754(const fp_value *val)
        for (; (byte_offset<<3) < desc.mantissa_size; byte_offset++)
                mantissa0 |= sc_sub_bits(_mant(value), mantissa_size, byte_offset) << ((byte_offset - 4) << 3);
 
-#ifdef SIZEOF_LONG_DOUBLE_8
-       mantissa0 &= 0x000FFFFF;  /* get rid of garbage */
-       buildval.val.high = sign << 31;
-       buildval.val.high |= exponent << 20;
-       buildval.val.high |= mantissa0;
-       buildval.val.low = mantissa1;
-#else
-       buildval.val.high = sign << 15;
-       buildval.val.high |= exponent;
-       buildval.val.mid = mantissa0;
-       buildval.val.low = mantissa1;
-#endif
+       if (long_double_size == 8) {
+               mantissa0 &= 0x000FFFFF;  /* get rid of garbage */
+               buildval.val_ld8.high = sign << 31;
+               buildval.val_ld8.high |= exponent << 20;
+               buildval.val_ld8.high |= mantissa0;
+               buildval.val_ld8.low = mantissa1;
+       } else {
+               buildval.val_ld12.high = sign << 15;
+               buildval.val_ld12.high |= exponent;
+               buildval.val_ld12.mid = mantissa0;
+               buildval.val_ld12.low = mantissa1;
+       }
 
        TRACEPRINTF(("val_to_float: %d-%x-%x%x\n", sign, exponent, mantissa0, mantissa1));
        return buildval.d;
 }
 
-fp_value *fc_cast(const fp_value *value, const ieee_descriptor_t *desc, fp_value *result)
+fp_value *fc_cast(const fp_value *value, const float_descriptor_t *desc,
+                  fp_value *result)
 {
        char *temp;
        int exp_offset, val_bias, res_bias;
@@ -1014,13 +1045,13 @@ fp_value *fc_cast(const fp_value *value, const ieee_descriptor_t *desc, fp_value
                return result;
        }
 
-       if (value->desc.clss == NAN) {
+       if (value->clss == FC_NAN) {
                if (sc_get_highest_set_bit(_mant(value)) == value->desc.mantissa_size + 1)
                        return fc_get_qnan(desc, result);
                else
                        return fc_get_snan(desc, result);
        }
-       else if (value->desc.clss == INF) {
+       else if (value->clss == FC_INF) {
                if (value->sign == 0)
                        return fc_get_plusinf(desc, result);
                else
@@ -1028,11 +1059,8 @@ fp_value *fc_cast(const fp_value *value, const ieee_descriptor_t *desc, fp_value
        }
 
        /* set the descriptor of the new value */
-       result->desc.exponent_size = desc->exponent_size;
-       result->desc.mantissa_size = desc->mantissa_size;
-       result->desc.explicit_one  = desc->explicit_one;
-       result->desc.clss          = value->desc.clss;
-
+       result->desc = *desc;
+       result->clss = value->clss;
        result->sign = value->sign;
 
        /* when the mantissa sizes differ normalizing has to shift to align it.
@@ -1046,7 +1074,7 @@ fp_value *fc_cast(const fp_value *value, const ieee_descriptor_t *desc, fp_value
        sc_add(_exp(value), temp, _exp(result));
 
        /* _normalize expects normalized radix point */
-       if (value->desc.clss == SUBNORMAL) {
+       if (value->clss == FC_SUBNORMAL) {
                sc_val_from_ulong(1, NULL);
                _shift_left(_mant(value), sc_get_buffer(), _mant(result));
        } else if (value != result) {
@@ -1060,15 +1088,12 @@ fp_value *fc_cast(const fp_value *value, const ieee_descriptor_t *desc, fp_value
        return result;
 }
 
-fp_value *fc_get_max(const ieee_descriptor_t *desc, fp_value *result)
+fp_value *fc_get_max(const float_descriptor_t *desc, fp_value *result)
 {
        if (result == NULL) result = calc_buffer;
 
-       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 = *desc;
+       result->clss = FC_NORMAL;
        result->sign = 0;
 
        sc_val_from_ulong((1 << desc->exponent_size) - 2, _exp(result));
@@ -1080,7 +1105,7 @@ fp_value *fc_get_max(const ieee_descriptor_t *desc, fp_value *result)
        return result;
 }
 
-fp_value *fc_get_min(const ieee_descriptor_t *desc, fp_value *result)
+fp_value *fc_get_min(const float_descriptor_t *desc, fp_value *result)
 {
        if (result == NULL) result = calc_buffer;
 
@@ -1090,15 +1115,12 @@ fp_value *fc_get_min(const ieee_descriptor_t *desc, fp_value *result)
        return result;
 }
 
-fp_value *fc_get_snan(const ieee_descriptor_t *desc, fp_value *result)
+fp_value *fc_get_snan(const float_descriptor_t *desc, fp_value *result)
 {
        if (result == NULL) result = calc_buffer;
 
-       result->desc.exponent_size = desc->exponent_size;
-       result->desc.mantissa_size = desc->mantissa_size;
-       result->desc.explicit_one  = desc->explicit_one;
-       result->desc.clss          = NAN;
-
+       result->desc = *desc;
+       result->clss = FC_NAN;
        result->sign = 0;
 
        sc_val_from_ulong((1 << desc->exponent_size) - 1, _exp(result));
@@ -1109,15 +1131,12 @@ fp_value *fc_get_snan(const ieee_descriptor_t *desc, fp_value *result)
        return result;
 }
 
-fp_value *fc_get_qnan(const ieee_descriptor_t *desc, fp_value *result)
+fp_value *fc_get_qnan(const float_descriptor_t *desc, fp_value *result)
 {
        if (result == NULL) result = calc_buffer;
 
-       result->desc.exponent_size = desc->exponent_size;
-       result->desc.mantissa_size = desc->mantissa_size;
-       result->desc.explicit_one  = desc->explicit_one;
-       result->desc.clss          = NAN;
-
+       result->desc = *desc;
+       result->clss = FC_NAN;
        result->sign = 0;
 
        sc_val_from_ulong((1 << desc->exponent_size) - 1, _exp(result));
@@ -1131,17 +1150,14 @@ fp_value *fc_get_qnan(const ieee_descriptor_t *desc, fp_value *result)
        return result;
 }
 
-fp_value *fc_get_plusinf(const ieee_descriptor_t *desc, fp_value *result)
+fp_value *fc_get_plusinf(const float_descriptor_t *desc, fp_value *result)
 {
        char *mant;
 
        if (result == NULL) result = calc_buffer;
 
-       result->desc.exponent_size = desc->exponent_size;
-       result->desc.mantissa_size = desc->mantissa_size;
-       result->desc.explicit_one  = desc->explicit_one;
-       result->desc.clss          = INF;
-
+       result->desc = *desc;
+       result->clss = FC_INF;
        result->sign = 0;
 
        sc_val_from_ulong((1 << desc->exponent_size) - 1, _exp(result));
@@ -1155,7 +1171,7 @@ fp_value *fc_get_plusinf(const ieee_descriptor_t *desc, fp_value *result)
        return result;
 }
 
-fp_value *fc_get_minusinf(const ieee_descriptor_t *desc, fp_value *result)
+fp_value *fc_get_minusinf(const float_descriptor_t *desc, fp_value *result)
 {
        if (result == NULL) result = calc_buffer;
 
@@ -1174,14 +1190,14 @@ int fc_comp(const fp_value *val_a, const fp_value *val_b)
         * Unordered if NaN or equal
         */
        if (val_a == val_b)
-               return val_a->desc.clss == NAN ? 2 : 0;
+               return val_a->clss == FC_NAN ? 2 : 0;
 
        /* unordered if one is a NaN */
-       if (val_a->desc.clss == NAN || val_b->desc.clss == NAN)
+       if (val_a->clss == FC_NAN || val_b->clss == FC_NAN)
                return 2;
 
        /* zero is equal independent of sign */
-       if ((val_a->desc.clss == ZERO) && (val_b->desc.clss == ZERO))
+       if ((val_a->clss == FC_ZERO) && (val_b->clss == FC_ZERO))
                return 0;
 
        /* different signs make compare easy */
@@ -1191,13 +1207,13 @@ int fc_comp(const fp_value *val_a, const fp_value *val_b)
        mul = val_a->sign ? -1 : 1;
 
        /* both infinity means equality */
-       if ((val_a->desc.clss == INF) && (val_b->desc.clss == INF))
+       if ((val_a->clss == FC_INF) && (val_b->clss == FC_INF))
                return 0;
 
        /* infinity is bigger than the rest */
-       if (val_a->desc.clss == INF)
+       if (val_a->clss == FC_INF)
                return  1 * mul;
-       if (val_b->desc.clss == INF)
+       if (val_b->clss == FC_INF)
                return -1 * mul;
 
        /* check first exponent, that mantissa if equal */
@@ -1215,7 +1231,7 @@ int fc_comp(const fp_value *val_a, const fp_value *val_b)
 
 int fc_is_zero(const fp_value *a)
 {
-       return a->desc.clss == ZERO;
+       return a->clss == FC_ZERO;
 }
 
 int fc_is_negative(const fp_value *a)
@@ -1225,17 +1241,17 @@ int fc_is_negative(const fp_value *a)
 
 int fc_is_inf(const fp_value *a)
 {
-       return a->desc.clss == INF;
+       return a->clss == FC_INF;
 }
 
 int fc_is_nan(const fp_value *a)
 {
-       return a->desc.clss == NAN;
+       return a->clss == FC_NAN;
 }
 
 int fc_is_subnormal(const fp_value *a)
 {
-       return a->desc.clss == SUBNORMAL;
+       return a->clss == FC_SUBNORMAL;
 }
 
 char *fc_print(const fp_value *val, char *buf, int buflen, unsigned base)
@@ -1247,14 +1263,14 @@ char *fc_print(const fp_value *val, char *buf, int buflen, unsigned base)
 
        switch (base) {
        case FC_DEC:
-               switch ((value_class_t)val->desc.clss) {
-               case INF:
+               switch ((value_class_t)val->clss) {
+               case FC_INF:
                        snprintf(buf, buflen, "%cINF", val->sign ? '-' : '+');
                        break;
-               case NAN:
+               case FC_NAN:
                        snprintf(buf, buflen, "NaN");
                        break;
-               case ZERO:
+               case FC_ZERO:
                        snprintf(buf, buflen, "0.0");
                        break;
                default:
@@ -1265,14 +1281,14 @@ char *fc_print(const fp_value *val, char *buf, int buflen, unsigned base)
                break;
 
        case FC_HEX:
-               switch ((value_class_t)val->desc.clss) {
-               case INF:
+               switch ((value_class_t)val->clss) {
+               case FC_INF:
                        snprintf(buf, buflen, "%cINF", val->sign ? '-' : '+');
                        break;
-               case NAN:
-                       snprintf(buf, buflen, "NAN");
+               case FC_NAN:
+                       snprintf(buf, buflen, "NaN");
                        break;
-               case ZERO:
+               case FC_ZERO:
                        snprintf(buf, buflen, "0.0");
                        break;
                default:
@@ -1317,16 +1333,16 @@ int fc_get_exponent(const fp_value *value)
 }
 
 /* Return non-zero if a given value can be converted lossless into another precision */
-int fc_can_lossless_conv_to(const fp_value *value, const ieee_descriptor_t *desc)
+int fc_can_lossless_conv_to(const fp_value *value, const float_descriptor_t *desc)
 {
        int v;
        int exp_bias;
 
        /* handle some special cases first */
-       switch (value->desc.clss) {
-       case ZERO:
-       case INF:
-       case NAN:
+       switch (value->clss) {
+       case FC_ZERO:
+       case FC_INF:
+       case FC_NAN:
                return 1;
        default:
                break;
@@ -1484,13 +1500,12 @@ fp_value *fc_int(const fp_value *a, fp_value *result)
 
 fp_value *fc_rnd(const fp_value *a, fp_value *result)
 {
-       if (result == NULL) result = calc_buffer;
-
-       (void) a;
+       (void)a;
+       (void)result;
        TRACEPRINTF(("%s ", fc_print(a, buffer, sizeof(buffer), FC_PACKED)));
        TRACEPRINTF(("rounded to integer "));
 
-       panic("fc_rnd() not yet implemented");
+       panic("not yet implemented");
 }
 
 /*
@@ -1498,7 +1513,7 @@ fp_value *fc_rnd(const fp_value *a, fp_value *result)
  */
 int fc_flt2int(const fp_value *a, void *result, ir_mode *dst_mode)
 {
-       if (a->desc.clss == NORMAL) {
+       if (a->clss == FC_NORMAL) {
                int exp_bias = (1 << (a->desc.exponent_size - 1)) - 1;
                int exp_val  = sc_val_to_long(_exp(a)) - exp_bias;
                int shift, highest;
@@ -1553,23 +1568,13 @@ int fc_flt2int(const fp_value *a, void *result, ir_mode *dst_mode)
                        sc_neg(result, result);
 
                return 1;
-       }
-       else if (a->desc.clss == ZERO) {
+       } else if (a->clss == FC_ZERO) {
                sc_zero(result);
                return 1;
        }
        return 0;
 }
 
-
-unsigned fc_set_immediate_precision(unsigned bits)
-{
-       unsigned old = immediate_prec;
-
-       immediate_prec = bits;
-       return old;
-}
-
 int fc_is_exact(void)
 {
        return fc_exact;