update copyright message
[libfirm] / ir / tv / fltcalc.c
index b38d5b9..53d4241 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
+ * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
  *
  * This file is part of libFirm.
  *
@@ -1063,6 +1063,9 @@ fp_value *fc_val_from_ieee754(LLDBL l, char exp_size, char mant_size, fp_value *
        if (result == NULL) result = calc_buffer;
        temp = alloca(value_size);
 
+       /* CLEAR the buffer */
+       memset(result, 0, fc_get_buffer_length());
+
        result->desc.exponent_size = exp_size;
        result->desc.mantissa_size = mant_size;
 
@@ -1627,6 +1630,7 @@ 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;
        TRACEPRINTF(("%s ", fc_print(a, buffer, sizeof(buffer), FC_PACKED)));
        TRACEPRINTF(("rounded to integer "));
 
@@ -1636,6 +1640,65 @@ fp_value *fc_rnd(const fp_value *a, fp_value *result) {
        return result;
 }
 
+/*
+ * convert a floating point value into an sc value ...
+ */
+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;
+
+               if (a->sign && !mode_is_signed(dst_mode)) {
+                       /* FIXME: for now we cannot convert this */
+                       return 0;
+               }
+
+               assert(exp_val >= 0 && "floating point value not integral before fc_flt2int() call");
+               shift = exp_val - a->desc.mantissa_size - 2;
+
+               if (shift > 0) {
+                       sc_shlI(_mant(a),  shift, 64, 0, result);
+               } else {
+                       sc_shrI(_mant(a), -shift, 64, 0, result);
+               }
+
+               /* check for overflow */
+               highest = sc_get_highest_set_bit(result);
+
+               if (mode_is_signed(dst_mode)) {
+                       if (highest == sc_get_lowest_set_bit(result)) {
+                               /* need extra test for MIN_INT */
+                               if (highest >= get_mode_size_bits(dst_mode)) {
+                                       /* FIXME: handle overflow */
+                                       return 0;
+                               }
+                       } else {
+                               if (highest >= get_mode_size_bits(dst_mode) - 1) {
+                                       /* FIXME: handle overflow */
+                                       return 0;
+                               }
+                       }
+               } else {
+                       if (highest >= get_mode_size_bits(dst_mode)) {
+                               /* FIXME: handle overflow */
+                               return 0;
+                       }
+               }
+
+               if (a->sign)
+                       sc_neg(result, result);
+
+               return 1;
+       }
+       else if (a->desc.clss == ZERO) {
+               sc_zero(result);
+               return 1;
+       }
+       return 0;
+}
+
+
 unsigned fc_set_immediate_precision(unsigned bits) {
        unsigned old = immediate_prec;