X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Ftv%2Ffltcalc.c;h=d6105a8972817303daeca99dd561e5a82658d86e;hb=0f234e2d94155d13c0e4727871125beda0eaa66d;hp=d153b90b51f15f7b4398438751a19a4c80aa1452;hpb=e07b61c6ed5d198a484761f8a40a4f26520d964d;p=libfirm diff --git a/ir/tv/fltcalc.c b/ir/tv/fltcalc.c index d153b90b5..d6105a897 100644 --- a/ir/tv/fltcalc.c +++ b/ir/tv/fltcalc.c @@ -24,29 +24,20 @@ * @author Mathias Heil * @version $Id$ */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif +#include "config.h" #include "fltcalc.h" #include "strcalc.h" -#include /* need isnan() and isinf() (will be changed)*/ +#include /* undef some reused constants defined by math.h */ #ifdef NAN # undef NAN #endif -#ifdef HAVE_INTTYPES_H -# include -#endif -#ifdef HAVE_STRING_H -# include -#endif -#ifdef HAVE_STDLIB_H -# include -#endif +#include +#include +#include #include #include @@ -817,7 +808,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 +1012,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 +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); @@ -1230,6 +1225,12 @@ fp_value *fc_cast(const fp_value *value, const ieee_descriptor_t *desc, fp_value else return fc_get_snan(desc, result); } + else if(value->desc.clss == INF) { + if (value->sign == 0) + return fc_get_plusinf(desc, result); + else + return fc_get_minusinf(desc, result); + } /* set the descriptor of the new value */ result->desc.exponent_size = desc->exponent_size; @@ -1331,7 +1332,10 @@ 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 ieee_descriptor_t *desc, fp_value *result) +{ + char *mant; + if (result == NULL) result = calc_buffer; result->desc.exponent_size = desc->exponent_size; @@ -1343,7 +1347,11 @@ fp_value *fc_get_plusinf(const ieee_descriptor_t *desc, fp_value *result) { sc_val_from_ulong((1 << desc->exponent_size) - 1, _exp(result)); - sc_val_from_ulong(0, _mant(result)); + mant = _mant(result); + sc_val_from_ulong(0, mant); + if (desc->explicit_one) { + sc_set_bit_at(mant, result->desc.mantissa_size + ROUNDING_BITS); + } return result; } @@ -1527,7 +1535,7 @@ int fc_can_lossless_conv_to(const fp_value *value, const ieee_descriptor_t *desc if (0 < v && v < (1 << desc->exponent_size) - 1) { /* exponent can be encoded, now check the mantissa */ v = value->desc.mantissa_size + ROUNDING_BITS - sc_get_lowest_set_bit(_mant(value)); - return v < desc->mantissa_size; + return v <= desc->mantissa_size; } return 0; } @@ -1687,24 +1695,34 @@ fp_value *fc_rnd(const fp_value *a, fp_value *result) { /* * convert a floating point value into an sc value ... */ -int fc_flt2int(const fp_value *a, void *result, ir_mode *dst_mode) { +int fc_flt2int(const fp_value *a, void *result, ir_mode *dst_mode) +{ if (a->desc.clss == 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; + int mantissa_size; + int tgt_bits; if (a->sign && !mode_is_signed(dst_mode)) { /* FIXME: for now we cannot convert this */ return 0; } + tgt_bits = get_mode_size_bits(dst_mode); + if (mode_is_signed(dst_mode)) + --tgt_bits; + 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; + if (tgt_bits < mantissa_size + 1) + tgt_bits = mantissa_size + 1; if (shift > 0) { - sc_shlI(_mant(a), shift, 64, 0, result); + sc_shlI(_mant(a), shift, tgt_bits, 0, result); } else { - sc_shrI(_mant(a), -shift, 64, 0, result); + sc_shrI(_mant(a), -shift, tgt_bits, 0, result); } /* check for overflow */