X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Ftv%2Ffltcalc.c;h=d6105a8972817303daeca99dd561e5a82658d86e;hb=0f234e2d94155d13c0e4727871125beda0eaa66d;hp=639f84815882d58cca619baaffd2804f9bdecc90;hpb=a7a3ee1e12b2d3854a5600a69d8bd14ac3369fc4;p=libfirm diff --git a/ir/tv/fltcalc.c b/ir/tv/fltcalc.c index 639f84815..d6105a897 100644 --- a/ir/tv/fltcalc.c +++ b/ir/tv/fltcalc.c @@ -24,21 +24,18 @@ * @author Mathias Heil * @version $Id$ */ - #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 +#include #include #include #include @@ -1228,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; @@ -1329,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; @@ -1341,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; } @@ -1685,27 +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"); mantissa_size = a->desc.mantissa_size + ROUNDING_BITS; shift = exp_val - mantissa_size; - mantissa_size += 1; + if (tgt_bits < mantissa_size + 1) + tgt_bits = mantissa_size + 1; if (shift > 0) { - sc_shlI(_mant(a), shift, mantissa_size, 0, result); + sc_shlI(_mant(a), shift, tgt_bits, 0, result); } else { - sc_shrI(_mant(a), -shift, mantissa_size, 0, result); + sc_shrI(_mant(a), -shift, tgt_bits, 0, result); } /* check for overflow */