Remove unnecessary conversions to wider modes as operands of Cmp.
[libfirm] / ir / tv / tv.c
index c3ea578..aecdf24 100644 (file)
@@ -101,8 +101,8 @@ static struct set *tarvals = NULL;   /* container for tarval structs */
 static struct set *values = NULL;    /* container for values */
 static tarval_int_overflow_mode_t int_overflow_mode = TV_OVERFLOW_WRAP;
 
-/* if this is defined TRUE, the constant folding for floating point is OFF */
-#define no_float 1
+/** if this is set non-zero, the constant folding for floating point is OFF */
+static int no_float = 0;
 
 /****************************************************************************
  *   private functions
@@ -276,7 +276,7 @@ tarval *new_tarval_from_str(const char *str, size_t len, ir_mode *mode)
                        return atoi(str) ? tarval_b_true : tarval_b_false;
 
        case irms_float_number:
-               switch(get_mode_size_bits(mode)) {
+               switch (get_mode_size_bits(mode)) {
                case 32:
                        fc_val_from_str(str, len, 8, 23, NULL);
                        break;
@@ -315,6 +315,7 @@ tarval *new_tarval_from_long(long l, ir_mode *mode) {
                /* same as integer modes */
        case irms_int_number:
                sc_val_from_long(l, NULL);
+               sign_extend(sc_get_buffer(), mode);
                return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
 
        case irms_float_number:
@@ -574,7 +575,7 @@ tarval *get_tarval_minus_one(ir_mode *mode) {
                return mode_is_signed(mode) ? new_tarval_from_double(-1.0, mode) : tarval_bad;
 
        case irms_int_number:
-               return mode_is_signed(mode) ? new_tarval_from_long(-1l, mode) : tarval_bad;
+               return new_tarval_from_long(-1l, mode);
        }
        return tarval_bad;
 }
@@ -743,7 +744,7 @@ pn_Cmp tarval_cmp(tarval *a, tarval *b) {
                return pn_Cmp_False;
 
        case irms_float_number:
-               if(no_float)
+               if (no_float)
                        return pn_Cmp_False;
                /*
                 * BEWARE: we cannot compare a == b here, because
@@ -1478,7 +1479,7 @@ char *get_tarval_bitpattern(tarval *tv) {
 unsigned char get_tarval_sub_bits(tarval *tv, unsigned byte_ofs) {
        switch (get_mode_arithmetic(tv->mode)) {
        case irma_twos_complement:
-               return sc_sub_bits(tv->value, tv->length, byte_ofs);
+               return sc_sub_bits(tv->value, get_mode_size_bits(tv->mode), byte_ofs);
        case irma_ieee754:
                return fc_sub_bits(tv->value, get_mode_size_bits(tv->mode), byte_ofs);
        default:
@@ -1528,7 +1529,7 @@ tarval_classification_t classify_tarval(tarval *tv) {
        else if (tv == get_mode_one(tv->mode))
                return TV_CLASSIFY_ONE;
        else if ((get_mode_sort(tv->mode) == irms_int_number)
-               && (tv == new_tarval_from_long(-1, tv->mode)))
+               && (tv == get_mode_minus_one(tv->mode)))
                return TV_CLASSIFY_ALL_ONE;
 
        return TV_CLASSIFY_OTHER;
@@ -1575,6 +1576,16 @@ int tarval_ieee754_get_exponent(tarval *tv) {
        return fc_get_exponent(tv->value);
 }
 
+/* Set the immediate precision for IEEE-754 results. */
+unsigned tarval_ieee754_set_immediate_precision(unsigned bits) {
+       return fc_set_immediate_precision(bits);
+}
+
+/* Returns non-zero if the result of the last IEEE-754 operation was exact. */
+unsigned tarval_ieee754_get_exact(void) {
+       return fc_is_exact();
+}
+
 /*
  * Sets the overflow mode for integer operations.
  */
@@ -1582,13 +1593,19 @@ void tarval_set_integer_overflow_mode(tarval_int_overflow_mode_t ov_mode) {
        int_overflow_mode = ov_mode;
 }
 
-/**
- * Get the overflow mode for integer operations.
- */
+/* Get the overflow mode for integer operations. */
 tarval_int_overflow_mode_t tarval_get_integer_overflow_mode(void) {
        return int_overflow_mode;
 }
 
+/* Enable/Disable floating point constant folding. */
+int tarval_enable_fp_ops(int enable) {
+       int old = !no_float;
+
+       no_float = !enable;
+       return old;
+}
+
 /**
  * default mode_info for output as HEX
  */