mproved mature method
[libfirm] / ir / tv / tv.c
index 9f4b02d..7b633ed 100644 (file)
@@ -42,7 +42,7 @@
 
 #include "tv_t.h"
 #include "set.h"            /* to store tarvals in */
-//#include "tune.h"           /* some constants */
+/* #include "tune.h" */          /* some constants */
 #include "entity_t.h"       /* needed to store pointers to entities */
 #include "irmode.h"         /* defines modes etc */
 #include "irmode_t.h"
@@ -53,7 +53,7 @@
 
 /** Size of hash tables.  Should correspond to average number of distinct constant
     target values */
-#define N_CONSTANTS    2048
+#define N_CONSTANTS 2048
 
 /* XXX hack until theres's a proper interface */
 #define BAD 1
@@ -279,7 +279,7 @@ tarval *new_tarval_from_str(const char *str, size_t len, ir_mode *mode)
       else if (strcasecmp(str, "false")) return tarval_b_true;
       else
         /* XXX This is C semantics */
-       return atoi(str) ? tarval_b_true : tarval_b_false;
+    return atoi(str) ? tarval_b_true : tarval_b_false;
 
     case irms_float_number:
       switch(get_mode_size_bits(mode)) {
@@ -419,7 +419,7 @@ int tarval_is_entity(tarval *tv)
   assert(tv);
   /* tv->value == NULL means dereferencing a null pointer */
   return ((get_mode_sort(tv->mode) == irms_reference) && (tv->value != NULL) && (tv->length == 0)
-         && (tv != tarval_P_void));
+      && (tv != tarval_P_void));
 }
 
 entity *tarval_to_entity(tarval *tv)
@@ -501,6 +501,11 @@ tarval *get_tarval_max(ir_mode *mode)
   ANNOUNCE();
   assert(mode);
 
+  if (get_mode_vector_elems(mode) > 1) {
+    /* vector arithmetic not implemented yet */
+    return tarval_bad;
+  }
+
   switch(get_mode_sort(mode))
   {
     case irms_reference:
@@ -541,6 +546,11 @@ tarval *get_tarval_min(ir_mode *mode)
   ANNOUNCE();
   assert(mode);
 
+  if (get_mode_vector_elems(mode) > 1) {
+    /* vector arithmetic not implemented yet */
+    return tarval_bad;
+  }
+
   switch(get_mode_sort(mode))
   {
     case irms_reference:
@@ -581,6 +591,11 @@ tarval *get_tarval_null(ir_mode *mode)
   ANNOUNCE();
   assert(mode);
 
+  if (get_mode_vector_elems(mode) > 1) {
+    /* vector arithmetic not implemented yet */
+    return tarval_bad;
+  }
+
   switch(get_mode_sort(mode))
   {
     case irms_control_flow:
@@ -608,6 +623,11 @@ tarval *get_tarval_one(ir_mode *mode)
   ANNOUNCE();
   assert(mode);
 
+  if (get_mode_vector_elems(mode) > 1) {
+    /* vector arithmetic not implemented yet */
+    return tarval_bad;
+  }
+
   switch(get_mode_sort(mode))
   {
     case irms_control_flow:
@@ -634,6 +654,11 @@ tarval *get_tarval_nan(ir_mode *mode)
   ANNOUNCE();
   assert(mode);
 
+  if (get_mode_vector_elems(mode) > 1) {
+    /* vector arithmetic not implemented yet */
+    return tarval_bad;
+  }
+
   if (get_mode_sort(mode) == irms_float_number) {
     switch(get_mode_size_bits(mode))
     {
@@ -660,6 +685,11 @@ tarval *get_tarval_inf(ir_mode *mode)
   ANNOUNCE();
   assert(mode);
 
+  if (get_mode_vector_elems(mode) > 1) {
+    /* vector arithmetic not implemented yet */
+    return tarval_bad;
+  }
+
   if (get_mode_sort(mode) == irms_float_number) {
     switch(get_mode_size_bits(mode))
     {
@@ -693,12 +723,18 @@ int tarval_is_negative(tarval *a)
   ANNOUNCE();
   assert(a);
 
+  if (get_mode_vector_elems(a->mode) > 1) {
+    /* vector arithmetic not implemented yet */
+    assert(0 && "tarval_is_negative is not allowed for vector modes");
+    return 0;
+  }
+
   switch (get_mode_sort(a->mode))
   {
     case irms_int_number:
       if (!mode_is_signed(a->mode)) return 0;
       else
-       return sc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0;
+    return sc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0;
 
     case irms_float_number:
       return fc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0;
@@ -741,7 +777,12 @@ pnc_number tarval_cmp(tarval *a, tarval *b)
   if (a == tarval_bad || b == tarval_bad) assert(0 && "Comparison with tarval_bad");
   if (a == tarval_undefined || b == tarval_undefined) return False;
   if (a == b) return Eq;
-  if (get_tarval_mode(a) != get_tarval_mode(b)) return False;
+  if (a->mode != b->mode) return False;
+
+  if (get_mode_vector_elems(a->mode) > 1) {
+    /* vector arithmetic not implemented yet */
+    assert(0 && "cmp not implemented for vector modes");
+  }
 
   /* Here the two tarvals are unequal and of the same mode */
   switch (get_mode_sort(a->mode))
@@ -783,6 +824,11 @@ tarval *tarval_convert_to(tarval *src, ir_mode *m)
 
   if (src->mode == m) return src;
 
+  if (get_mode_vector_elems(src->mode) > 1) {
+    /* vector arithmetic not implemented yet */
+    return tarval_bad;
+  }
+
   switch (get_mode_sort(src->mode))
   {
     case irms_control_flow:
@@ -793,7 +839,7 @@ tarval *tarval_convert_to(tarval *src, ir_mode *m)
     /* cast float to something */
     case irms_float_number:
       switch (get_mode_sort(m)) {
-       case irms_float_number:
+    case irms_float_number:
           switch (get_mode_size_bits(m))
           {
             case 32:
@@ -809,7 +855,7 @@ tarval *tarval_convert_to(tarval *src, ir_mode *m)
               break;
           }
           return get_tarval(fc_get_buffer(), fc_get_buffer_length(), m);
-         break;
+      break;
 
         case irms_int_number:
           switch (GET_FLOAT_TO_INT_MODE())
@@ -828,7 +874,7 @@ tarval *tarval_convert_to(tarval *src, ir_mode *m)
            * an intermediate representation is needed here first. */
           /*  return get_tarval(); */
           return tarval_bad;
-         break;
+      break;
 
         default:
           /* the rest can't be converted */
@@ -908,6 +954,8 @@ tarval *tarval_not(tarval *a)
   assert(a);
   assert(mode_is_int(a->mode)); /* bitwise negation is only allowed for integer */
 
+  /* works for vector mode without changes */
+
   switch (get_mode_sort(a->mode))
   {
     case irms_int_number:
@@ -932,6 +980,11 @@ tarval *tarval_neg(tarval *a)
   assert(mode_is_num(a->mode)); /* negation only for numerical values */
   assert(mode_is_signed(a->mode)); /* negation is difficult without negative numbers, isn't it */
 
+  if (get_mode_vector_elems(a->mode) > 1) {
+    /* vector arithmetic not implemented yet */
+    return tarval_bad;
+  }
+
   switch (get_mode_sort(a->mode))
   {
     case irms_int_number:
@@ -960,6 +1013,11 @@ tarval *tarval_add(tarval *a, tarval *b)
   assert(b);
   assert((a->mode == b->mode) || (get_mode_sort(a->mode) == irms_character && mode_is_int(b->mode)));
 
+  if (get_mode_vector_elems(a->mode) > 1 || get_mode_vector_elems(b->mode) > 1) {
+    /* vector arithmetic not implemented yet */
+    return tarval_bad;
+  }
+
   switch (get_mode_sort(a->mode))
   {
     case irms_character:
@@ -990,6 +1048,10 @@ tarval *tarval_sub(tarval *a, tarval *b)
   assert(b);
   assert((a->mode == b->mode) || (get_mode_sort(a->mode) == irms_character && mode_is_int(b->mode)));
 
+  if (get_mode_vector_elems(a->mode) > 1 || get_mode_vector_elems(b->mode) > 1) {
+    /* vector arithmetic not implemented yet */
+    return tarval_bad;
+  }
   switch (get_mode_sort(a->mode))
   {
     case irms_character:
@@ -1020,6 +1082,11 @@ tarval *tarval_mul(tarval *a, tarval *b)
   assert(b);
   assert((a->mode == b->mode) && mode_is_num(a->mode));
 
+  if (get_mode_vector_elems(a->mode) > 1) {
+    /* vector arithmetic not implemented yet */
+    return tarval_bad;
+  }
+
   switch (get_mode_sort(a->mode))
   {
     case irms_int_number:
@@ -1047,6 +1114,11 @@ tarval *tarval_quo(tarval *a, tarval *b)
   assert(b);
   assert((a->mode == b->mode) && mode_is_float(a->mode));
 
+  if (get_mode_vector_elems(a->mode) > 1) {
+    /* vector arithmetic not implemented yet */
+    return tarval_bad;
+  }
+
   fc_div(a->value, b->value, NULL);
   return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
 }
@@ -1062,6 +1134,11 @@ tarval *tarval_div(tarval *a, tarval *b)
   assert(b);
   assert((a->mode == b->mode) && mode_is_int(a->mode));
 
+  if (get_mode_vector_elems(a->mode) > 1) {
+    /* vector arithmetic not implemented yet */
+    return tarval_bad;
+  }
+
   /* x/0 error */
   if (b == get_mode_null(b->mode)) return tarval_bad;
   /* modes of a,b are equal */
@@ -1080,6 +1157,11 @@ tarval *tarval_mod(tarval *a, tarval *b)
   assert(b);
   assert((a->mode == b->mode) && mode_is_int(a->mode));
 
+  if (get_mode_vector_elems(a->mode) > 1) {
+    /* vector arithmetic not implemented yet */
+    return tarval_bad;
+  }
+
   /* x/0 error */
   if (b == get_mode_null(b->mode)) return tarval_bad;
   /* modes of a,b are equal */
@@ -1098,6 +1180,11 @@ tarval *tarval_abs(tarval *a)
   assert(a);
   assert(mode_is_num(a->mode));
 
+  if (get_mode_vector_elems(a->mode) > 1) {
+    /* vector arithmetic not implemented yet */
+    return tarval_bad;
+  }
+
   switch (get_mode_sort(a->mode))
   {
     case irms_int_number:
@@ -1133,6 +1220,8 @@ tarval *tarval_and(tarval *a, tarval *b)
   assert(b);
   assert(a->mode == b->mode);
 
+  /* works even for vector modes */
+
   switch(get_mode_sort(a->mode))
   {
     case irms_internal_boolean:
@@ -1158,6 +1247,8 @@ tarval *tarval_or (tarval *a, tarval *b)
   assert(b);
   assert(a->mode == b->mode);
 
+  /* works even for vector modes */
+
   switch (get_mode_sort(a->mode))
   {
     case irms_internal_boolean:
@@ -1183,6 +1274,8 @@ tarval *tarval_eor(tarval *a, tarval *b)
   assert(b);
   assert((a->mode == b->mode));
 
+  /* works even for vector modes */
+
   switch (get_mode_sort(a->mode))
   {
     case irms_internal_boolean:
@@ -1209,6 +1302,11 @@ tarval *tarval_shl(tarval *a, tarval *b)
   assert(b);
   assert(mode_is_int(a->mode) && mode_is_int(b->mode));
 
+  if (get_mode_vector_elems(a->mode) > 1 || get_mode_vector_elems(a->mode) > 1) {
+    /* vector arithmetic not implemented yet */
+    return tarval_bad;
+  }
+
   if (get_mode_modulo_shift(a->mode) != 0)
   {
     temp_val = alloca(sc_get_buffer_length());
@@ -1234,6 +1332,11 @@ tarval *tarval_shr(tarval *a, tarval *b)
   assert(b);
   assert(mode_is_int(a->mode) && mode_is_int(b->mode));
 
+  if (get_mode_vector_elems(a->mode) > 1 || get_mode_vector_elems(a->mode) > 1) {
+    /* vector arithmetic not implemented yet */
+    return tarval_bad;
+  }
+
   if (get_mode_modulo_shift(a->mode) != 0)
   {
     temp_val = alloca(sc_get_buffer_length());
@@ -1244,7 +1347,7 @@ tarval *tarval_shr(tarval *a, tarval *b)
   else
     temp_val = (char*)b->value;
 
-  sc_shr(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL);
+  sc_shr(a->value, temp_val, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL);
   return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
 }
 
@@ -1259,6 +1362,11 @@ tarval *tarval_shrs(tarval *a, tarval *b)
   assert(b);
   assert(mode_is_int(a->mode) && mode_is_int(b->mode));
 
+  if (get_mode_vector_elems(a->mode) > 1 || get_mode_vector_elems(a->mode) > 1) {
+    /* vector arithmetic not implemented yet */
+    return tarval_bad;
+  }
+
   if (get_mode_modulo_shift(a->mode) != 0)
   {
     temp_val = alloca(sc_get_buffer_length());
@@ -1269,7 +1377,7 @@ tarval *tarval_shrs(tarval *a, tarval *b)
   else
     temp_val = (char*)b->value;
 
-  sc_shrs(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL);
+  sc_shrs(a->value, temp_val, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL);
   return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
 }
 
@@ -1284,6 +1392,11 @@ tarval *tarval_rot(tarval *a, tarval *b)
   assert(b);
   assert(mode_is_int(a->mode) && mode_is_int(b->mode));
 
+  if (get_mode_vector_elems(a->mode) > 1 || get_mode_vector_elems(a->mode) > 1) {
+    /* vector arithmetic not implemented yet */
+    return tarval_bad;
+  }
+
   if (get_mode_modulo_shift(a->mode) != 0)
   {
     temp_val = alloca(sc_get_buffer_length());
@@ -1294,7 +1407,7 @@ tarval *tarval_rot(tarval *a, tarval *b)
   else
     temp_val = (char*)b->value;
 
-  sc_rot(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL);
+  sc_rot(a->value, temp_val, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL);
   return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
 }
 
@@ -1327,17 +1440,17 @@ int tarval_snprintf(char *buf, size_t len, tarval *tv)
 
       case TVO_DECIMAL:
         str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_DEC);
-       break;
+    break;
 
       case TVO_OCTAL:
         str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_OCT);
-       break;
+    break;
 
       case TVO_HEX:
       case TVO_NATIVE:
       default:
         str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_HEX);
-       break;
+    break;
       }
       return snprintf(buf, len, "%s%s%s", prefix, str, suffix);
 
@@ -1363,24 +1476,24 @@ int tarval_snprintf(char *buf, size_t len, tarval *tv)
           if (get_entity_peculiarity((entity *)tv->value) != peculiarity_description)
             return snprintf(buf, len, "%s%s%s", prefix, get_entity_ld_name((entity *)tv->value), suffix);
           else {
-           if (mode_info->mode_output == TVO_NATIVE)
+        if (mode_info->mode_output == TVO_NATIVE)
               return snprintf(buf, len, "NULL");
-           else
+        else
               return snprintf(buf, len, "0");
-         }
-       }
+      }
+    }
         else {
-         if (size > tv->length) {
-           memcpy(buf, tv->value, tv->length);
-           buf[tv->length] = '\0';
-         }
-         else {
-           /* truncated */
-           memcpy(buf, tv->value, size-1);
-           buf[size-1] = '\0';
-         }
+      if (size > tv->length) {
+        memcpy(buf, tv->value, tv->length);
+        buf[tv->length] = '\0';
+      }
+      else {
+        /* truncated */
+        memcpy(buf, tv->value, size-1);
+        buf[size-1] = '\0';
+      }
           return tv->length;
-       }
+    }
       else
         return snprintf(buf, len, "void");
 
@@ -1562,6 +1675,14 @@ void init_tarval_2(void)
   tarval_set_mode_output_option(mode_P,  &reference_output);
 }
 
+/* free all memory occupied by tarval. */
+void finish_tarval(void) {
+  finish_strcalc ();
+  finish_fltcalc ();
+  del_set(tarvals); tarvals = NULL;
+  del_set(values);  values = NULL;
+}
+
 /****************************************************************************
  *   end of tv.c
  ****************************************************************************/