- fix most of the -Wunreachable-code and -Wlogical-op warnings
[libfirm] / ir / tv / tv.c
index ea7b6ff..bf32031 100644 (file)
     target values */
 #define N_CONSTANTS 2048
 
-/* get the integer overflow mode */
-#define GET_OVERFLOW_MODE() int_overflow_mode
-
 /* unused, float to int doesn't work yet */
-enum float_to_int_mode {
+typedef enum float_to_int_mode {
        TRUNCATE,
        ROUND
-};
+} float_to_int_mode;
 
-#define GET_FLOAT_TO_INT_MODE() TRUNCATE
+static float_to_int_mode current_float_to_int_mode = TRUNCATE;
 
 #define SWITCH_NOINFINITY 0
 #define SWITCH_NODENORMALS 0
@@ -236,7 +233,7 @@ static tarval *get_tarval_overflow(const void *value, int length, ir_mode *mode)
 
        case irms_int_number:
                if (sc_comp(value, get_mode_max(mode)->value) == 1) {
-                       switch (GET_OVERFLOW_MODE()) {
+                       switch (tarval_get_integer_overflow_mode()) {
                        case TV_OVERFLOW_SATURATE:
                                return get_mode_max(mode);
                        case TV_OVERFLOW_WRAP:
@@ -253,7 +250,7 @@ static tarval *get_tarval_overflow(const void *value, int length, ir_mode *mode)
                        }
                }
                if (sc_comp(value, get_mode_min(mode)->value) == -1) {
-                       switch (GET_OVERFLOW_MODE()) {
+                       switch (tarval_get_integer_overflow_mode()) {
                        case TV_OVERFLOW_SATURATE:
                                return get_mode_min(mode);
                        case TV_OVERFLOW_WRAP: {
@@ -271,15 +268,19 @@ static tarval *get_tarval_overflow(const void *value, int length, ir_mode *mode)
                break;
 
        case irms_float_number:
-               if (SWITCH_NOINFINITY && fc_is_inf(value)) {
+#ifdef SWITCH_NOINFINITY
+               if (fc_is_inf(value)) {
                        /* clip infinity to maximum value */
                        return fc_is_negative(value) ? get_mode_min(mode) : get_mode_max(mode);
                }
+#endif
 
-               if (SWITCH_NODENORMALS && fc_is_subnormal(value)) {
+#ifdef SWITCH_NODENORMALS
+               if (fc_is_subnormal(value)) {
                        /* clip denormals to zero */
                        return get_mode_null(mode);
                }
+#endif
                break;
 
        default:
@@ -317,13 +318,74 @@ static const ieee_descriptor_t *get_descriptor(const ir_mode *mode)
        /* case 128: return &quad_desc; */
        default:
                panic("Unsupported mode in get_descriptor()");
-               return NULL;
        }
 }
 
-/*
- *   public functions declared in tv.h
- */
+tarval *new_integer_tarval_from_str(const char *str, size_t len, char sign,
+                                    unsigned char base, ir_mode *mode)
+{
+       void *buffer;
+       int   ok;
+
+       buffer = alloca(sc_get_buffer_length());
+
+       ok = sc_val_from_str(sign, base, str, len, buffer);
+       if (!ok)
+               return tarval_bad;
+
+       return get_tarval_overflow(buffer, sc_get_buffer_length(), mode);
+}
+
+static tarval *new_tarval_from_str_int(const char *str, size_t len,
+                                       ir_mode *mode)
+{
+       void    *buffer;
+       unsigned base = 10;
+       char     sign = 1;
+       int      ok;
+
+       /* skip leading spaces */
+       while (len > 0 && str[0] == ' ') {
+               ++str;
+               --len;
+       }
+       if (len == 0)
+               return tarval_bad;
+
+       /* 1 sign character allowed */
+       if (str[0] == '-') {
+               sign = -1;
+               ++str;
+               --len;
+       } else if (str[0] == '+') {
+               ++str;
+               --len;
+       }
+
+       /* a number starting with '0x' is hexadeciaml,
+        * a number starting with '0' (and at least 1 more char) is octal */
+       if (len >= 2 && str[0] == '0') {
+               if (str[1] == 'x' || str[1] == 'X') {
+                       str += 2;
+                       len -= 2;
+                       base = 16;
+               } else {
+                       ++str;
+                       --len;
+                       base = 8;
+               }
+       }
+       if (len == 0)
+               return tarval_bad;
+
+       buffer = alloca(sc_get_buffer_length());
+
+       ok = sc_val_from_str(sign, base, str, len, buffer);
+       if (!ok)
+               return tarval_bad;
+
+       return get_tarval_overflow(buffer, sc_get_buffer_length(), mode);
+}
 
 /*
  * Constructors =============================================================
@@ -362,8 +424,7 @@ tarval *new_tarval_from_str(const char *str, size_t len, ir_mode *mode)
                        return get_tarval_null(mode);
                /* FALLTHROUGH */
        case irms_int_number:
-               sc_val_from_str(str, len, NULL, mode);
-               return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
+               return new_tarval_from_str_int(str, len, mode);
        }
        panic("Unsupported tarval creation with mode %F", mode);
 }
@@ -390,9 +451,8 @@ tarval *new_tarval_from_long(long l, ir_mode *mode)
                return new_tarval_from_double((long double)l, mode);
 
        default:
-               assert(0 && "unsupported mode sort");
+               panic("unsupported mode sort");
        }
-       return NULL;
 }
 
 /* returns non-zero if can be converted to long */
@@ -794,7 +854,6 @@ pn_Cmp tarval_cmp(tarval *a, tarval *b)
 
        if (a == tarval_bad || b == tarval_bad) {
                panic("Comparison with tarval_bad");
-               return pn_Cmp_False;
        }
 
        if (a == tarval_undefined || b == tarval_undefined)
@@ -805,7 +864,7 @@ pn_Cmp tarval_cmp(tarval *a, tarval *b)
 
        if (get_mode_n_vector_elems(a->mode) > 1) {
                /* vector arithmetic not implemented yet */
-               assert(0 && "cmp not implemented for vector modes");
+               panic("cmp not implemented for vector modes");
        }
 
        /* Here the two tarvals are unequal and of the same mode */
@@ -854,6 +913,7 @@ tarval *tarval_convert_to(tarval *src, ir_mode *dst_mode)
        char                    *buffer;
        fp_value                *res;
        const ieee_descriptor_t *desc;
+       int                      len;
 
        carry_flag = -1;
 
@@ -883,16 +943,13 @@ tarval *tarval_convert_to(tarval *src, ir_mode *dst_mode)
                        return get_tarval(fc_get_buffer(), fc_get_buffer_length(), dst_mode);
 
                case irms_int_number:
-                       switch (GET_FLOAT_TO_INT_MODE()) {
+                       switch (current_float_to_int_mode) {
                        case TRUNCATE:
                                res = fc_int(src->value, NULL);
                                break;
                        case ROUND:
                                res = fc_rnd(src->value, NULL);
                                break;
-                       default:
-                               panic("Unsupported float to int conversion mode in tarval_convert_to()");
-                               break;
                        }
                        buffer = alloca(sc_get_buffer_length());
                        if (! fc_flt2int(res, buffer, dst_mode))
@@ -928,11 +985,11 @@ tarval *tarval_convert_to(tarval *src, ir_mode *dst_mode)
                        buffer = alloca(100);
                        /* decimal string representation because hexadecimal output is
                         * interpreted unsigned by fc_val_from_str, so this is a HACK */
-                       snprintf(buffer, 100, "%s",
+                       len = snprintf(buffer, 100, "%s",
                                sc_print(src->value, get_mode_size_bits(src->mode), SC_DEC, mode_is_signed(src->mode)));
                        buffer[100 - 1] = '\0';
                        desc = get_descriptor(dst_mode);
-                       fc_val_from_str(buffer, 0, desc, NULL);
+                       fc_val_from_str(buffer, len, desc, NULL);
                        return get_tarval(fc_get_buffer(), fc_get_buffer_length(), dst_mode);
 
                default:
@@ -985,8 +1042,7 @@ tarval *tarval_not(tarval *a)
                return tarval_bad;
 
        default:
-               assert(0 && "bitwise negation is only allowed for integer and boolean");
-               return tarval_bad;
+               panic("bitwise negation is only allowed for integer and boolean");
        }
 }
 
@@ -1277,7 +1333,7 @@ tarval *tarval_abs(tarval *a)
                return a;
 
        default:
-               return tarval_bad;
+               break;
        }
        return tarval_bad;
 }
@@ -1301,8 +1357,7 @@ tarval *tarval_and(tarval *a, tarval *b)
                return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
 
        default:
-               assert(0 && "operation not defined on mode");
-               return tarval_bad;
+               panic("operation not defined on mode");
        }
 }
 
@@ -1322,8 +1377,7 @@ tarval *tarval_andnot(tarval *a, tarval *b)
                return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
 
        default:
-               assert(0 && "operation not defined on mode");
-               return tarval_bad;
+               panic("operation not defined on mode");
        }
 }
 
@@ -1346,8 +1400,7 @@ tarval *tarval_or(tarval *a, tarval *b)
                return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
 
        default:
-               assert(0 && "operation not defined on mode");
-               return tarval_bad;
+               panic("operation not defined on mode");
        }
 }
 
@@ -1370,8 +1423,7 @@ tarval *tarval_eor(tarval *a, tarval *b)
                return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
 
        default:
-               assert(0 && "operation not defined on mode");
-               return tarval_bad;;
+               panic("operation not defined on mode");
        }
 }