X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Ftv%2Ffltcalc.c;h=d153b90b51f15f7b4398438751a19a4c80aa1452;hb=afbbc0b1ccd684c4c24bfd43d0f994123245f39f;hp=5e2fc0aad37c4fc894e0b749de50d22a596a47ec;hpb=1da31809e58c2bc55a82597f5a83c205822d5541;p=libfirm diff --git a/ir/tv/fltcalc.c b/ir/tv/fltcalc.c index 5e2fc0aad..d153b90b5 100644 --- a/ir/tv/fltcalc.c +++ b/ir/tv/fltcalc.c @@ -182,6 +182,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 +399,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 +440,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 +480,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 +556,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 +567,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 +579,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 +643,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 +657,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 +672,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 +680,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); @@ -1321,7 +1337,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 +1434,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 +1456,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 +1487,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);