Added two new modes: mode_BAD the mode of tarval_bad and mode_ANY, the mode of tarval...
[libfirm] / ir / tv / tv.c
index 0506060..f9cea87 100644 (file)
@@ -42,7 +42,7 @@
 #include <stdlib.h>         /* atoi() */
 #include <string.h>         /* nice things for strings */
 
-#include <malloc.h>
+#include <stdlib.h>
 #include "tv_t.h"
 #include "set.h"            /* to store tarvals in */
 #include "tune.h"           /* some constants */
@@ -50,8 +50,6 @@
 #include "irmode.h"         /* defines modes etc */
 #include "irmode_t.h"
 #include "irnode.h"         /* defines boolean return values */
-#include "xprintf.h"
-#include "xp_help.h"
 #include "host.h"
 #include "strcalc.h"
 #include "fltcalc.h"
@@ -100,7 +98,7 @@ static void _fail_verify(tarval *tv, const char* file, int line)
   assert(0);
 }
 
-static void tarval_verify(tarval *tv)
+inline static void tarval_verify(tarval *tv)
 {
   assert(tv);
   assert(tv->mode);
@@ -171,6 +169,9 @@ static int overflows(tarval *tv)
       break;
 
     case irms_float_number:
+      /*
+       * TODO: check NaNs
+       */
       if (fc_comp(tv->value, get_mode_max(tv->mode)->value) == 1) return 1;
       if (fc_comp(tv->value, get_mode_min(tv->mode)->value) == -1) return 1;
       break;
@@ -252,7 +253,7 @@ char *tarval_to_str(tarval *tv)
 #endif
 
 /*
- * helper function, creta a tarval from long
+ * helper function, create a tarval from long
  */
 tarval *new_tarval_from_long(long l, ir_mode *mode)
 {
@@ -577,6 +578,16 @@ int tarval_is_negative(tarval *a)
   }
 }
 
+/*
+ * test if null, 1 means 'yes'
+ */
+int tarval_is_null(tarval *a)
+{
+  ir_mode *m = get_tarval_mode(a);
+
+  return a == get_tarval_null(m);
+}
+
 /*
  * comparison
  */
@@ -632,20 +643,32 @@ tarval *tarval_convert_to(tarval *src, ir_mode *m)
       break;
 
     case irms_float_number:
+      switch (get_mode_sort(m)) {
+       case irms_float_number:
+          tv.mode   = m;
+          tv.length = src->length;
+          tv.value  = src->value;
+          if (overflows(&tv)) {
+            return tarval_bad;
+         }
+
+          return INSERT_TARVAL(&tv);
+
+       default:
+         break;
+      }
       break;
 
     case irms_int_number:
-      switch (get_mode_sort(m))
-      {
+      switch (get_mode_sort(m)) {
         case irms_int_number:
         case irms_character:
-          tv.mode = m;
+          tv.mode   = m;
           tv.length = src->length;
-          tv.value = src->value;
+          tv.value  = src->value;
           if (overflows(&tv))
-          {
             return tarval_bad;
-          }
+
           return INSERT_TARVAL(&tv);
 
         case irms_internal_boolean:
@@ -871,7 +894,12 @@ tarval *tarval_and(tarval *a, tarval *b)
   ANNOUNCE();
   assert(a);
   assert(b);
-  assert((a->mode == b->mode) && mode_is_int(a->mode));
+  assert(a->mode == b->mode);
+
+  /* GL: needed for easy optimization. */
+  if (a->mode == mode_b) return (a == tarval_b_false) ? a : b;
+
+  assert(mode_is_int(a->mode));
 
   sc_and(a->value, b->value);
   return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
@@ -885,7 +913,13 @@ tarval *tarval_or (tarval *a, tarval *b)
   ANNOUNCE();
   assert(a);
   assert(b);
-  assert((a->mode == b->mode) && mode_is_int(a->mode));
+  assert(a->mode == b->mode);
+
+  /* GL: needed for easy optimization. */
+  if (a->mode == mode_b) return (a == tarval_b_true) ? a : b;
+
+
+  assert(mode_is_int(a->mode));
 
   sc_or(a->value, b->value);
   return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
@@ -961,85 +995,6 @@ tarval *tarval_rot(tarval *a, tarval *b)
   return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
 }
 
-/*
- * Output of tarvals
- */
-int tarval_print(XP_PAR1, const xprintf_info *info ATTRIBUTE((unused)), XP_PARN)
-{
-  static const tarval_mode_info default_info = { TVO_NATIVE, NULL, NULL };
-
-  tarval *tv;
-  const char *str;
-  char buf[100];
-  const tarval_mode_info *mode_info;
-  const char *prefix, *suffix;
-
-  ANNOUNCE();
-
-  tv = XP_GETARG(tarval *, 0);
-  mode_info = tv->mode->tv_priv;
-  if (! mode_info)
-    mode_info = &default_info;
-  prefix = mode_info->mode_prefix ? mode_info->mode_prefix : "";
-  suffix = mode_info->mode_suffix ? mode_info->mode_suffix : "";
-
-  switch (get_mode_sort(tv->mode))
-  {
-    case irms_int_number:
-    case irms_character:
-      switch (mode_info->mode_output) {
-
-      case TVO_DECIMAL:
-        str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_DEC);
-       break;
-
-      case TVO_OCTAL:
-        str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_OCT);
-       break;
-
-      case TVO_HEX:
-      case TVO_NATIVE:
-      default:
-        str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_HEX);
-       break;
-      }
-      return XPF3R("%s%s%s", prefix, str, suffix);
-
-    case irms_float_number:
-      return XPF3R("%s%s%s", prefix, fc_print_dec(tv->value, buf, sizeof(buf)), suffix);
-
-    case irms_reference:
-      if (tv->value != NULL)
-        if (tarval_is_entity(tv))
-          if (get_entity_peculiarity((entity *)tv->value) == existent)
-            return XPF1R("&(%I)", get_entity_ld_ident((entity *)tv->value));
-          else
-            return XPSR("NULL");
-        else
-          return XPMR((char*)tv->value, tv->length);
-      else
-        return XPSR("void");
-
-    case irms_internal_boolean:
-      switch (mode_info->mode_output) {
-
-      case TVO_DECIMAL:
-      case TVO_OCTAL:
-      case TVO_HEX:
-      case TVO_BINARY:
-        return XPF3R("%s%c%s", prefix, (tv == tarval_b_true) ? '1' : '0', suffix);
-
-      case TVO_NATIVE:
-      default:
-        return XPF3R("%s%s%s", prefix, (tv == tarval_b_true) ? "true" : "false", suffix);
-      }
-
-    case irms_auxiliary:
-      return XPSR("<BAD>");
-  }
-
-  return 0;
-}
 
 /*
  * Output of tarvals
@@ -1088,11 +1043,16 @@ int tarval_snprintf(char *buf, size_t len, tarval *tv)
 
     case irms_reference:
       if (tv->value != NULL)
-        if (tarval_is_entity(tv))
+        if (tarval_is_entity(tv)) {
           if (get_entity_peculiarity((entity *)tv->value) == existent)
-            return snprintf(buf, len, "&(%s)", id_to_str(get_entity_ld_ident((entity *)tv->value)));
-          else
-            return snprintf(buf, len, "NULL");
+            return snprintf(buf, len, "%s%s%s", prefix, get_entity_ld_name((entity *)tv->value), suffix);
+          else {
+           if (mode_info->mode_output == TVO_NATIVE)
+              return snprintf(buf, len, "NULL");
+           else
+              return snprintf(buf, len, "0");
+         }
+       }
         else {
          if (size > tv->length) {
            memcpy(buf, tv->value, tv->length);
@@ -1129,6 +1089,21 @@ int tarval_snprintf(char *buf, size_t len, tarval *tv)
   return 0;
 }
 
+
+/**
+ * Output of tarvals to stdio.
+ */
+int tarval_printf(tarval *tv) {
+  char buf[1024];
+  int res;
+
+  res = tarval_snprintf(buf, sizeof(buf), tv);
+  assert(res < sizeof(buf) && "buffer to small for tarval_snprintf");
+  printf(buf);
+  return res;
+}
+
+
 char *tarval_bitpattern(tarval *tv)
 {
   return NULL;
@@ -1212,6 +1187,16 @@ static const tarval_mode_info hex_output = {
   NULL,
 };
 
+/**
+ * default mode_info for output as reference
+ */
+static const tarval_mode_info reference_output = {
+  TVO_NATIVE,
+  "&(",
+  ")",
+};
+
+
 /*
  * Initialization of the tarval module: called after init_mode()
  */
@@ -1220,10 +1205,10 @@ void init_tarval_2(void)
   ANNOUNCE();
 
   tarval_bad = (tarval*)malloc(sizeof(tarval));
-  tarval_bad->mode = NULL;
+  tarval_bad->mode = mode_BAD;
 
   tarval_undefined = (tarval*)malloc(sizeof(tarval));
-  tarval_undefined->mode = NULL;
+  tarval_undefined->mode = mode_ANY;
 
   tarval_b_true = (tarval*)malloc(sizeof(tarval));
   tarval_b_true->mode = mode_b;
@@ -1250,6 +1235,7 @@ void init_tarval_2(void)
   tarval_set_mode_output_option(mode_Iu, &hex_output);
   tarval_set_mode_output_option(mode_Ls, &hex_output);
   tarval_set_mode_output_option(mode_Lu, &hex_output);
+  tarval_set_mode_output_option(mode_P,  &reference_output);
 }
 
 /****************************************************************************