Changed inf/nan to remove non-partabel ieee754.h file
[libfirm] / ir / tv / tv.c
index 38d248b..59829f5 100644 (file)
 
 /* $Id$ */
 
+/****i* tv/implementation
+ *
+ * AUTHORS
+ *    Christian von Roques
+ *    Matthias Heil
+ *
+ * NOTES
+ *    Internal storage for tarvals, 1st draft:
+ *   Integers as well as pointers are stored in a hex formatted string holding
+ *   16 characters. Booleans are not stored as there are only two of them.
+ *
+ *    Floats are just reinterpreted as byte strings, because I am not sure if
+ *   there is loss if I convert float to long double and back and furthermore
+ *   the implementation of a fully ieee compatible floating point emulation
+ *   is not sensible for now
+ *    With this information it is easy to decide the kind of stored value:
+ *   Integers have size 16, floats 4, doubles 8, long doubles 12.
+ ******/
+
 /* This implementation assumes:
-   * target characters/strings can be represented as type `char'/`char *',
-   * host's type `long'/`unsigned long' can hold values of mode `l'/`L',
-   * both host and target have two's complement integral arithmetic,
-     host's C operators `/' and `%' match target's div and mod.
-     target_max_<mode> == (1<<k)-1 for some k>0
-     target_min_<mode> == -target_max_<mode>-1
-     target_max_<Mode> == target_max_<mode>-target_min_<mode>
    * both host and target have IEEE-754 floating-point arithmetic.  */
 
 /* !!! float and double divides MUST NOT SIGNAL !!! */
 /* @@@ query the floating-point expception status flags */
 
-/* @@@ ToDo: tarval_convert_to is not fully implemented! */
 /* @@@ Problem: All Values are stored twice, once as Univ_*s and a 2nd
    time in their real target mode. :-( */
-/* @@@ Perhaps use a set instead of a pset: new tarvals allocated on
-   stack, copied into set by tarval_identify() if really new.  If
-   tarval_identify() discards often enough, the extra copy for kept
-   values is cheaper than the extra obstack_alloc()/free() for
-   discarded ones.  */
+
+#define MAX_INT_LENGTH 8
+#define CHAR_BUFFER_SIZE ((MAX_INT_LENGTH) * 2)
 
 #ifdef HAVE_CONFIG_H
 # include <config.h>
 #endif
 
-# include "xprintf.h"
-#include <assert.h>
-#include <limits.h>
-#include <errno.h>
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "pset.h"
-#define TOBSTACK_ID "tv"
-#include "obst.h"
-#include "ieee754.h"
-#include "tune.h"
-#include "xp_help.h"
-#include "tv_t.h"
-#include "entity_t.h"
-#include "ident_t.h"
-#include "irmode.h"
-#include "irnode.h"
+#include <assert.h>         /* assertions */
+#include <stdlib.h>         /* atoi() */
+#include <string.h>         /* nice things for strings */
 
-static struct obstack tv_obst; /* obstack for all the target values */
-static pset *tarvals;          /* pset containing pointers to _all_ tarvals */
+#include <malloc.h>
+#include "tv_t.h"
+#include "set.h"            /* to store tarvals in */
+#include "tune.h"           /* some constants */
+#include "entity_t.h"       /* needed to store pointers to entities */
+#include "irmode.h"         /* defines modes etc */
+#include "irnode.h"         /* defines boolean return values */
+#include "xprintf.h"
+#include "xp_help.h"
+#include "host.h"
+#include "strcalc.h"
+#include "fltcalc.h"
 
-/* currently building an object with tarval_start() & friends ? */
-#define BUILDING obstack_object_size (&tv_obst)
+/****************************************************************************
+ *   local definitions and macros
+ ****************************************************************************/
+#ifndef NDEBUG
+#  define TARVAL_VERIFY(a) tarval_verify((a))
+#else
+#  define TARVAL_VERIFY(a) ((void)0)
+#endif
 
-/* bcopy is not ISO C */
-#define bcopy(X, Y, Z) memcpy((Y), (X), (Z))
+#define INSERT_TARVAL(tv) ((tarval*)set_insert(tarvals, (tv), sizeof(tarval), hash_tv((tv))))
+#define FIND_TARVAL(tv) ((tarval*)set_find(tarvals, (tv), sizeof(tarval), hash_tv((tv))))
 
+#define INSERT_VALUE(val, size) (set_insert(values, (val), size, hash_val((val), size)))
+#define FIND_VALUE(val, size) (set_find(values, (val), size, hash_val((val), size)))
 
-/* special tarvals: */
-tarval *tarval_bad;
-tarval *tarval_b_false;
-tarval *tarval_b_true;
-tarval *tarval_D_NaN;
-tarval *tarval_D_Inf;
-tarval *tarval_P_void;
-tarval *tarval_mode_null[irm_max];
-tarval *tarval_mode_min[irm_max];
-tarval *tarval_mode_max[irm_max];
-
-tarval *get_tarval_bad      ()              { return tarval_bad;     }
-tarval *get_tarval_b_false  ()              { return tarval_b_false; }
-tarval *get_tarval_b_true   ()              { return tarval_b_true;  }
-tarval *get_tarval_D_NaN    ()              { return tarval_D_NaN;   }
-tarval *get_tarval_D_Inf    ()              { return tarval_D_Inf;   }
-tarval *get_tarval_P_void   ()              { return tarval_P_void;  }
-tarval *get_tarval_mode_null(ir_mode *mode)
-  { return tarval_mode_null[get_mode_modecode(mode)]; }
-tarval *get_tarval_mode_min (ir_mode *mode)
-  { return tarval_mode_min[get_mode_modecode(mode)];  }
-tarval *get_tarval_mode_max (ir_mode *mode)
-  { return tarval_mode_max[get_mode_modecode(mode)];  }
-
-# if 0
-/* @@@ depends on order of ir_mode */
-static tarval_sInt min_sInt[8] = {
-  TARGET_SIMIN (c), 0,
-  TARGET_SIMIN (h), 0,
-  TARGET_SIMIN (i), 0,
-  TARGET_SIMIN (l), 0
-};
-static tarval_sInt max_sInt[8] = {
-  TARGET_SIMAX (c), TARGET_UIMAX (C),
-  TARGET_SIMAX (h), TARGET_UIMAX (H),
-  TARGET_SIMAX (i), TARGET_UIMAX (I),
-  TARGET_SIMAX (l), TARGET_UIMAX (L)
-};
-# endif
-
-/* Used to be in irmode.h, replaced now. */
-# define is_Int(m) ((m) <= irm_Lu && (m) >= irm_Bs) /* old */
-
-/* return a mode-specific value */
-
-tarval_F
-tv_val_F (tarval *tv)
+#define fail_verify(a) _fail_verify((a), __FILE__, __LINE__)
+#if 0
+static long long count = 0;
+#  define ANNOUNCE() printf(__FILE__": call no. %lld (%s)\n", count++, __FUNCTION__);
+#else
+#  define ANNOUNCE() ((void)0)
+#endif
+/****************************************************************************
+ *   private variables
+ ****************************************************************************/
+static struct set *tarvals;   /* container for tarval structs */
+static struct set *values;    /* container for values */
+
+/****************************************************************************
+ *   private functions
+ ****************************************************************************/
+#ifndef NDEBUG
+static int hash_val(const void *value, unsigned int length);
+static int hash_tv(tarval *tv);
+static void _fail_verify(tarval *tv, const char* file, int line)
 {
-  return tv->u.F;
+  /* print a memory image of the tarval and throw an assertion */
+  if (tv)
+    printf("%s:%d: Invalid tarval:\n  mode: %s\n value: [%p]\n", file, line, get_mode_name(tv->mode), tv->value);
+  else
+    printf("%s:%d: Invalid tarval (null)", file, line);
+  assert(0);
 }
 
-tarval_D
-tv_val_D (tarval *tv)
+static void tarval_verify(tarval *tv)
 {
-  return tv->u.D;
-}
+  assert(tv);
+  assert(tv->mode);
+  assert(tv->value);
 
-tarval_E
-tv_val_E (tarval *tv)
-{
-  return tv->u.E;
+  if ((tv == tarval_bad) || (tv == tarval_undefined)) return;
+  if ((tv == tarval_b_true) || (tv == tarval_b_false)) return;
+
+  if (!FIND_TARVAL(tv)) fail_verify(tv);
+  if (tv->length > 0 && !FIND_VALUE(tv->value, tv->length)) fail_verify(tv);
+
+  return;
 }
+#endif /* NDEBUG */
 
-tarval_sInt
-tv_val_sInt (tarval *tv)
+static int hash_tv(tarval *tv)
 {
-  return tv->u.sInt;
+  return ((unsigned int)tv->value ^ (unsigned int)tv->mode) + tv->length;
 }
 
-tarval_uInt
-tv_val_uInt (tarval *tv)
+static int hash_val(const void *value, unsigned int length)
 {
-  return tv->u.uInt;
+  unsigned int i;
+  unsigned int hash = 0;
+
+  /* scramble the byte - array */
+  for (i = 0; i < length; i++)
+  {
+    hash += (hash << 5) ^ (hash >> 27) ^ ((char*)value)[i];
+    hash += (hash << 11) ^ (hash >> 17);
+  }
+
+  return hash;
 }
 
-tarval_P
-tv_val_P (tarval *tv)
+/* finds tarval with value/mode or creates new tarval*/
+static tarval *get_tarval(const void *value, int length, ir_mode *mode)
 {
-  return tv->u.P;
+  tarval tv;
+
+  tv.mode = mode;
+  tv.length = length;
+  if (length > 0)
+    /* if there already is such a value, it is returned, else value
+     * is copied into the set */
+    tv.value = INSERT_VALUE(value, length);
+  else
+    tv.value = value;
+
+  /* if there is such a tarval, it is returned, else tv is copied
+   * into the set */
+  return (tarval *)INSERT_TARVAL(&tv);
 }
 
-bool
-tv_val_b (tarval *tv)
+/**
+ * Returns non-zero if a tarval overflows.
+ *
+ * @todo Implementation did not work on all modes
+ */
+static int overflows(tarval *tv)
 {
-  return tv->u.b;
-}
+  switch (get_mode_sort(tv->mode))
+  {
+    case character:
+    case int_number:
+      if (sc_comp(tv->value, get_mode_max(tv->mode)->value) == 1) return 1;
+      if (sc_comp(tv->value, get_mode_min(tv->mode)->value) == -1) return 1;
+      break;
 
+    case float_number:
+      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;
 
-/* Overflows `sInt' signed integral `mode'?  */
-static INLINE bool
-sInt_overflow (tarval_sInt sInt, ir_mode *mode)
-{
-  assert (is_Int(get_mode_modecode(mode)));
-  return (get_mode_min(mode) && get_mode_max(mode)  /* only valid after firm initialization */
-         && (sInt < tv_val_sInt (get_mode_min(mode))
-             || tv_val_sInt (get_mode_max(mode)) < sInt));
+    default:
+      break;
+  }
+
+  return 0;
 }
 
+/****************************************************************************
+ *   public variables declared in tv.h
+ ****************************************************************************/
+tarval *tarval_bad;
+tarval *tarval_undefined;
+tarval *tarval_b_false;
+tarval *tarval_b_true;
+tarval *tarval_P_void;
 
-/* Overflows `uInt' unsigned integral `mode'?  */
-static INLINE bool
-uInt_overflow (tarval_uInt uInt, ir_mode *mode)
+/****************************************************************************
+ *   public functions declared in tv.h
+ ****************************************************************************/
+/*
+ * Constructors =============================================================
+ */
+tarval *new_tarval_from_str(const char *str, size_t len, ir_mode *mode)
 {
-  assert (is_Int(get_mode_modecode(mode)));
-  return (get_mode_max(mode)   /* only valid after firm initialization */
-         && tv_val_uInt (get_mode_max(mode)) < uInt);
-}
+  ANNOUNCE();
+  assert(str);
+  assert(len);
+  assert(mode);
+
+  switch (get_mode_sort(mode))
+  {
+    case auxiliary:
+      assert(0);
+      break;
 
+    case internal_boolean:
+      /* match tTrRuUeE/fFaAlLsSeE */
+      if (strcasecmp(str, "true")) return tarval_b_true;
+      else if (strcasecmp(str, "false")) return tarval_b_true;
+      else
+       return atoi(str) ? tarval_b_true : tarval_b_false;
 
-#ifndef NDEBUG
-void
-_tarval_vrfy (const tarval *val)
-{
-  assert (val);
-  switch (get_mode_modecode(val->mode)) {
-    /* floating */
-  case irm_F:
-  case irm_D:
-  case irm_E:
-    break;
-    /* integral */
-  case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu: {
-    //    printf("Tarval is %lu\n", val->u.uInt);
-    assert (!uInt_overflow (val->u.uInt, val->mode));
-    } break;
-  case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
-    assert (!sInt_overflow (val->u.sInt, val->mode)); break;
-  case irm_C:
-  case irm_U:
-    break;
-  case irm_P:
-    if (val->u.P.ent) {
-      assert (val->u.P.ent->kind == k_entity);
-    }
-    assert (   val->u.P.xname || val->u.P.ent
-           || !tarval_P_void || (val == tarval_P_void));
-    break;
-  case irm_b:
-    assert ((unsigned)val->u.b <= 1); break;
-  default:
-    assert (val->mode == mode_T);
-    break;
+    case float_number:
+      fc_val_from_str(str, len);
+      return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
+
+    case int_number:
+    case character:
+      sc_val_from_str(str, len);
+      return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
+
+    case reference:
+      return get_tarval(str, len, mode);
   }
-}
-#endif
 
+  assert(0);  /* can't be reached, can it? */
+  return NULL;
+}
 
-#ifdef STATS
+#if 0
+int tarval_is_str(tarval *tv)
+{
+  ANNOUNCE();
+  assert(tv);
 
-static void
-tarval_stats (void)
+  return ((get_mode_sort(tv->mode) == reference) && (tv->value != NULL) && (tv->length > 0));
+}
+char *tarval_to_str(tarval *tv)
 {
-  pset_stats (tarvals);
+  ANNOUNCE();
+  assert(tarval_is_str(tv));
+  return (char *)tv->value;
 }
-
 #endif
 
-
-/* Return the canonical tarval * for tv.
-   May destroy everything allocated on tv_obst after tv!  */
-static tarval *
-tarval_identify (tarval *tv)
+tarval *new_tarval_from_long(long l, ir_mode *mode)
 {
-  tarval *o;
+  ANNOUNCE();
+  assert(mode && !(get_mode_sort(mode) == auxiliary));
 
-  o = pset_insert (tarvals, tv, tarval_hash (tv));
+  switch(get_mode_sort(mode))
+  {
+    case internal_boolean:
+      /* XXX C-Semantics ! */
+      return l ? tarval_b_true : tarval_b_false ;
 
-  if (o != tv) {
-    obstack_free (&tv_obst, (void *)tv);
-  }
+    case int_number:
+    case character:
+      sc_val_from_long(l);
+      return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
 
-  TARVAL_VRFY (o);
-  return o;
-}
+    case float_number:
+      return new_tarval_from_double((long double)l, mode);
 
+    case reference:
+      return l ? tarval_bad : get_tarval(NULL, 0, mode);  /* null pointer or tarval_bad */
 
-/* Return 0 iff a equals b.  Bitwise identical NaNs compare equal.  */
-static int
-tarval_cmp (const void *p, const void *q)
-{
-  const tarval *a = p;
-  const tarval *b = q;
-
-  TARVAL_VRFY (a);
-  TARVAL_VRFY (b);
-
-  if (a == b) return 0;
-  if ((char *)a->mode - (char *)b->mode)
-    return (char *)a->mode - (char *)b->mode;
-
-  switch (get_mode_modecode(a->mode)) {
-    /* floating */
-  case irm_F:
-    return memcmp (&a->u.F, &b->u.F, sizeof (a->u.F));
-  case irm_D:
-    return memcmp (&a->u.D, &b->u.D, sizeof (a->u.D));
-  case irm_E:
-    return memcmp (&a->u.E, &b->u.E, sizeof (a->u.E));
-    /* unsigned */
-  case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
-    if (sizeof (int) == sizeof (tarval_uInt)) {
-      return a->u.uInt - b->u.uInt;
-    }
-    return a->u.uInt != b->u.uInt;
-    /* signed */
-  case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
-    if (sizeof (int) == sizeof (tarval_sInt)) {
-      return a->u.sInt - b->u.sInt;
-    }
-    return a->u.sInt != b->u.sInt;
-  case irm_C:
-    return a->u.C - b->u.C;
-  case irm_U:
-    return a->u.U - b->u.U;
-  case irm_P:
-    if (a->u.P.ent || b->u.P.ent)
-      return (char *)a->u.P.ent - (char *)b->u.P.ent;
-    if (a->u.P.xname && b->u.P.xname)
-      return strcmp (a->u.P.xname, b->u.P.xname);
-    return a->u.P.xname - b->u.P.xname;
-  case irm_b:
-    return a->u.b - b->u.b;
-  default: assert (0);
+    default:
+      assert(0);
   }
+  return NULL;
 }
 
-
-unsigned
-tarval_hash (tarval *tv)
+int tarval_is_long(tarval *tv)
 {
-  unsigned h;
-
-  h = get_mode_modecode(tv->mode) * 0x421u;
-  switch (get_mode_modecode(tv->mode)) {
-  case irm_T:
-    h = 0x94b527ce; break;
-  case irm_F:
-    /* quick & dirty */
-    { union { float f; unsigned u; } u;
-      assert (sizeof (float) <= sizeof (unsigned));
-      u.u = 0; u.f = tv->u.F;
-      h ^= u.u;
-      break;
-    }
-  case irm_D:
-    /* quick & dirty */
-    { union { double d; unsigned u[2]; } u;
-      assert (sizeof (double) <= 2*sizeof (unsigned));
-      u.u[0] = u.u[1] = 0; u.d = tv->u.D;
-      h ^= u.u[0] ^ u.u[1];
-      break;
-    }
-  case irm_E:
-    { union { long double e; unsigned u[3]; } u;
-      assert (sizeof (long double) <= 3*sizeof (unsigned));
-      u.u[0] = u.u[1] = u.u[2] = 0; u.e = tv->u.E;
-      h ^= u.u[0] ^ u.u[1] ^ u.u[2];
-      break;
-    }
-  case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
-    h ^= tv->u.uInt; break;
-  case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
-    h ^= tv->u.sInt; break;
-  case irm_C:
-    h ^= tv->u.C; break;
-  case irm_U:
-    h ^= tv->u.U; break;
-  case irm_P:
-    if (tv->u.P.ent) {
-      /* @@@ lower bits not random, watch for collisions; perhaps
-        replace by tv->u.p.ent - (entity *)0 */
-      h ^= ((char *)tv->u.P.ent - (char *)0) / 64;
-    } else if (tv->u.P.xname) {
-      /* Of course, strlen() in a hash function is a mistake, but this
-         case should be really rare.  */
-      h ^= ID_HASH (tv->u.P.xname, strlen (tv->u.P.xname));
-    } else {                   /* void */
-      h^= 0x2b592b88;
-    }
-    break;
-  case irm_b:
-    h ^= tv->u.b; break;
-  default:
-    assert(0);
-  }
-  return h;
+  ANNOUNCE();
+  return ((get_mode_sort(tv->mode) == int_number) || (get_mode_sort(tv->mode) == character));
 }
 
-
-/*** ***************** Initialization ************************************* ***/
-
-void
-tarval_init_1 (void)
+/* this might overflow the machine's long, so use only with small values */
+long tarval_to_long(tarval* tv)
 {
-  obstack_init (&tv_obst);
-  obstack_alignment_mask (&tv_obst) = ALIGNOF (tarval) - 1;
-  assert (IS_POW2 (ALIGNOF (tarval)));
+  ANNOUNCE();
+  assert(tv && get_mode_sort(tv->mode) == int_number);
 
-  /* initialize the target value table */
-  tarvals = new_pset (tarval_cmp, TUNE_NCONSTANTS);
+  return sc_val_to_long(tv->value); /* might overflow */
 }
 
-void
-tarval_init_2 (void)
+tarval *new_tarval_from_double(long double d, ir_mode *mode)
 {
-  tarval *tv;
-  union ieee754_double x;
-
-  /* assumed by tarval_hash(): */
-  assert (sizeof (float) * CHAR_BIT == 32);
-  assert (sizeof (double) * CHAR_BIT == 64);
-
-# if 0
-  /* assumed by tarval_sInt & friends: */
-  assert (   (irm_C == irm_c+1) && (irm_h == irm_C+1)
-         && (irm_H == irm_h+1) && (irm_i == irm_H+1)
-         && (irm_I == irm_i+1) && (irm_l == irm_I+1)
-         && (irm_L == irm_l+1));
-
-  /* assumed everywhere: */
-  for (i = 0;  i <= irm_L-irm_c;  i += 2) {
-    assert (   IS_POW2 (max_sInt[i+1]+1)
-           && (min_sInt[i] == -max_sInt[i]-1)
-           && ((tarval_uInt)max_sInt[i+1] == (tarval_uInt)max_sInt[i]-min_sInt[i]));
-  }
-# endif
-
-
-  tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
-  tv->mode = mode_T;
-  tarval_bad = tarval_identify (tv);
-
-  tarval_b_false = tarval_from_long (mode_b, 0);
-  tarval_b_true = tarval_from_long (mode_b, 1);
-
-  /* IsInf <-> exponent == 0x7ff && ! (bits | fraction_low) */
-  tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
-  tv->mode = mode_D;
-  x.ieee.negative = 0;
-  x.ieee.exponent = 0x7ff;
-  x.ieee.mantissa0 = 0;
-  x.ieee.mantissa1 = 0;
-  tv->u.D = x.d;
-  tarval_D_Inf = tarval_identify (tv);
-
-  /* IsNaN <-> exponent==0x7ff  && (qnan_bit | bits | fraction_low) */
-  tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
-  tv->mode = mode_D;
-  x.ieee_nan.negative = 0;
-  x.ieee_nan.exponent = 0x7ff;
-  x.ieee_nan.quiet_nan = 1;    /* @@@ quiet or signalling? */
-  x.ieee_nan.mantissa0 = 42;
-  x.ieee_nan.mantissa1 = 0;
-  assert(x.d != x.d /* x.d is NaN */);
-  tv->u.D = x.d;
-  tarval_D_NaN = tarval_identify (tv);
-
-  tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
-  tv->mode = mode_P;
-  tv->u.P.xname = NULL;
-  tv->u.P.ent = NULL;
-  tv->u.P.tv = NULL;
-  tarval_P_void = tarval_identify (tv);
-
-  tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
-
-
-  tarval_mode_null [irm_F] = tarval_from_long (mode_F, 0);
-  tarval_mode_null [irm_D] = tarval_from_long (mode_D, 0);
-  tarval_mode_null [irm_E] = tarval_from_long (mode_E, 0);
-  tarval_mode_null [irm_Bs] = tarval_from_long (mode_Bs, 0);
-  tarval_mode_null [irm_Bu] = tarval_from_long (mode_Bu, 0);
-  tarval_mode_null [irm_Hs] = tarval_from_long (mode_Hs, 0);
-  tarval_mode_null [irm_Hu] = tarval_from_long (mode_Hu, 0);
-  tarval_mode_null [irm_Is] = tarval_from_long (mode_Is, 0);
-  tarval_mode_null [irm_Iu] = tarval_from_long (mode_Iu, 0);
-  tarval_mode_null [irm_Ls] = tarval_from_long (mode_Ls, 0);
-  tarval_mode_null [irm_Lu] = tarval_from_long (mode_Lu, 0);
-  tarval_mode_null [irm_C] = tarval_from_long (mode_C, 0);
-  tarval_mode_null [irm_U] = tarval_from_long (mode_U, 0);
-  tarval_mode_null [irm_b] = tarval_b_false;
-  tarval_mode_null [irm_P] = tarval_P_void;
+  ANNOUNCE();
+  assert(mode && (get_mode_sort(mode) == float_number));
+
+  fc_val_from_float(d);
+  return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
 }
 
+int tarval_is_double(tarval *tv)
+{
+  ANNOUNCE();
+  assert(tv);
 
-/*** ********************** Constructors for tarvals ********************** ***/
+  return (get_mode_sort(tv->mode) == float_number);
+}
 
-/* copy from src to dst len chars omitting '_'. */
-static char *
-stripcpy (char *dst, const char *src, size_t len)
+long double tarval_to_double(tarval *tv)
 {
-  char *d = dst;
+  ANNOUNCE();
+  assert(tarval_is_double(tv));
 
-  while (len--) {
-    if (*src == '_') src++;
-    else *d++ = *src++;
-  }
-  *d = 0;                      /* make it 0-terminated. */
-
-  return dst;
+  return fc_val_to_float(tv->value);
 }
 
-tarval *
-tarval_F_from_str (const char *s, size_t len)
+/* The tarval represents the address of the entity.  As the address must
+   be constant the entity must have as owner the global type. */
+tarval *new_tarval_from_entity (entity *ent, ir_mode *mode)
 {
-  tarval *tv;
-  char *buf;
-  char *eptr;
+  ANNOUNCE();
+  assert(ent);
+  assert(mode && (get_mode_sort(mode) == reference));
 
-  assert (!BUILDING);
+  return get_tarval((void *)ent, 0, mode);
+}
+int tarval_is_entity(tarval *tv)
+{
+  ANNOUNCE();
+  assert(tv);
+  /* tv->value == NULL means dereferencing a null pointer */
+  return ((get_mode_sort(tv->mode) == reference) && (tv->value != NULL) && (tv->length == 0));
+}
 
-  buf = alloca (len+1);
-  stripcpy (buf, s, len);
+entity *tarval_to_entity(tarval *tv)
+{
+  ANNOUNCE();
+  assert(tv);
 
-  tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
-  tv->mode = mode_F;
-  tv->u.F = (float)strtod (buf, &eptr);
-  assert (eptr == buf+strlen(buf));
+  if (tarval_is_entity(tv))
+    return (entity *)tv->value;
+  else {
+    assert(0 && "tarval did not represent an entity");
+    return NULL;
+  }
+}
 
-  return tarval_identify (tv);
+/*
+ * Access routines for tarval fields ========================================
+ */
+#ifdef TARVAL_ACCESS_DEFINES
+#  undef get_tarval_mode
+#endif
+ir_mode *get_tarval_mode (tarval *tv)       /* get the mode of the tarval */
+{
+  ANNOUNCE();
+  assert(tv);
+  return tv->mode;
 }
+#ifdef TARVAL_ACCESS_DEFINES
+#  define get_tarval_mode(tv) (tv)->mode
+#endif
 
+/*
+ * Special value query functions ============================================
+ *
+ * These functions calculate and return a tarval representing the requested
+ * value.
+ * The functions get_mode_{Max,Min,...} return tarvals retrieved from these
+ * functions, but these are stored on initialization of the irmode module and
+ * therefore the irmode functions should be prefered to the functions below.
+ */
+
+tarval *get_tarval_bad(void)
+{
+  ANNOUNCE();
+  return tarval_bad;
+}
+tarval *get_tarval_undefined(void)
+{
+  ANNOUNCE();
+  return tarval_undefined;
+}
+tarval *get_tarval_b_false(void)
+{
+  ANNOUNCE();
+  return tarval_b_false;
+}
+tarval *get_tarval_b_true(void)
+{
+  ANNOUNCE();
+  return tarval_b_true;
+}
+tarval *get_tarval_P_void(void)
+{
+  ANNOUNCE();
+  return tarval_P_void;
+}
 
-tarval *
-tarval_D_from_str (const char *s, size_t len)
+tarval *get_tarval_max(ir_mode *mode)
 {
-  tarval *tv;
-  char *buf;
-  char *eptr;
+  ANNOUNCE();
+  assert(mode);
 
-  assert (!BUILDING);
+  switch(get_mode_sort(mode))
+  {
+    case reference:
+    case auxiliary:
+      assert(0);
+      break;
 
-  buf = alloca (len+1);
-  stripcpy (buf, s, len);
+    case internal_boolean:
+      return tarval_b_true;
 
-  tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
-  tv->mode = mode_D;
-  tv->u.D = strtod (buf, &eptr);
-  assert (eptr == buf+strlen(buf));
+    case float_number:
+      fc_get_max(get_mode_size_bits(mode));
+      return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
 
-  return tarval_identify (tv);
+    case int_number:
+    case character:
+      sc_max_from_bits(get_mode_size_bits(mode), mode_is_signed(mode));
+      return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
+  }
+  return tarval_bad;
 }
 
-tarval *
-tarval_int_from_str (const char *s, size_t len, int base, ir_mode *m)
+tarval *get_tarval_min(ir_mode *mode)
 {
-  long val;
-  char *eptr;
-  char *buf;
-
-  assert (mode_is_int(m));
-  assert (!BUILDING);
-
-  buf = alloca (len+1);
-  stripcpy (buf, s, len);
-
-  errno = 0;
-  val = strtol(buf, &eptr, base);    /* strtoll */
-  assert (eptr == buf+strlen(buf));
-  if ((errno == ERANGE)               &&
-      ((m == mode_Ls) || (m == mode_Lu))  ) {
-    printf("WARNING: Constant %s not representable. Continuing with %ld.\n",
-          s, val);
-  }
+  ANNOUNCE();
+  assert(mode);
 
-  return tarval_from_long(m, val);
-}
+  switch(get_mode_sort(mode))
+  {
+    case reference:
+    case auxiliary:
+      assert(0);
+      break;
 
-/* Create a tarval with mode `m' and value `val' casted to the type that
-   represents such tarvals on host.  The resulting value must be legal
-   for mode `m'.  */
-tarval *
-tarval_from_long (ir_mode *m, long val)
-{
-  tarval *tv;
+    case internal_boolean:
+      return tarval_b_false;
 
-  assert (!BUILDING);
-
-  if (m == mode_T) return tarval_bad;
-
-  tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
-
-  tv->mode = m;
-  switch (get_mode_modecode(m)) {
-    /* floating */
-  case irm_F:
-    tv->u.F = val; break;
-  case irm_D:
-    tv->u.D = val; break;
-  case irm_E:
-    /* @@@ not yet implemented */
-    break;
-    /* unsigned */
-  case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
-    tv->u.uInt = val; break;
-    /* signed */
-  case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
-    tv->u.sInt = val; break;
-  case irm_P:
-    assert(!val);
-    obstack_free (&tv_obst, tv);
-    return tarval_P_void;
-  case irm_C:
-    tv->u.C = val; break;
-  case irm_U:
-    tv->u.U = val; break;
-  case irm_b:
-    tv->u.b = !!val;           /* u.b must be 0 or 1 */
-    break;
-  default:
-    assert(0);
-  }
+    case float_number:
+      fc_get_min(get_mode_size_bits(mode));
+      return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
 
-  return tarval_identify (tv);
+    case int_number:
+    case character:
+      sc_min_from_bits(get_mode_size_bits(mode), mode_is_signed(mode));
+      return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
+  }
+  return tarval_bad;
 }
 
-
-tarval *
-tarval_P_from_str (const char *xname)
+tarval *get_tarval_null(ir_mode *mode)
 {
-  tarval *tv;
+  ANNOUNCE();
+  assert(mode);
+
+  switch(get_mode_sort(mode))
+  {
+    case auxiliary:
+    case internal_boolean:
+      assert(0);
+      break;
 
-  assert (!BUILDING);
+    case float_number:
+      return new_tarval_from_double(0.0, mode);
 
-  tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
+    case int_number:
+    case character:
+      return new_tarval_from_long(0l,  mode);
 
-  tv->mode = mode_P;
-  tv->u.P.xname = obstack_copy0 (&tv_obst, xname, strlen (xname));
-  tv->u.P.ent = NULL;
-  tv->u.P.tv = NULL;
-  return tarval_identify (tv);
+    case reference:
+      return tarval_P_void;
+  }
+  return tarval_bad;
 }
 
-
-tarval *
-tarval_P_from_entity (entity *ent)
+tarval *get_tarval_one(ir_mode *mode)
 {
-  tarval *tv;
-
-  assert (!BUILDING);
-  //assert(ent && "no entity given");
+  ANNOUNCE();
+  assert(mode);
+
+  switch(get_mode_sort(mode))
+  {
+    case auxiliary:
+    case internal_boolean:
+    case reference:
+      assert(0);
+      break;
 
-  tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
+    case float_number:
+      return new_tarval_from_double(1.0, mode);
 
-  tv->mode = mode_P;
-  tv->u.P.xname = NULL;
-  tv->u.P.ent = ent;
-  tv->u.P.tv = NULL;
-  return tarval_identify (tv);
+    case int_number:
+    case character:
+      return new_tarval_from_long(1l, mode);
+      break;
+  }
+  return tarval_bad;
 }
 
-
-/* Routines for building a tarval step by step follow.
-   Legal calling sequences:
-     tarval_start()
-     No constructors except tarval_append() and tarval_append1 ()
-     tarval_finish_as() or tarval_cancel() */
-
-/* Begin building a tarval.  */
-void
-tarval_start (void)
+tarval *get_tarval_nan(ir_mode *mode)
 {
-  assert (!BUILDING);
-  obstack_blank (&tv_obst, sizeof (tarval));
-}
-
+  ANNOUNCE();
+  assert(mode);
 
-/* Append `n' chars from `p' to the tarval currently under construction.  */
-void
-tarval_append (const char *p, size_t n)
-{
-  assert (BUILDING);
-  obstack_grow (&tv_obst, p, n);
+  if (get_mode_sort(mode) == float_number) {
+    fc_get_nan();
+    return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
+  }
+  else {
+    assert(0 && "tarval is not floating point");
+    return tarval_bad;
+  }
 }
 
-
-/* Append `ch' to the tarval currently under construction.  */
-void
-tarval_append1 (char ch)
+tarval *get_tarval_inf(ir_mode *mode)
 {
-  assert (BUILDING);
-  obstack_1grow (&tv_obst, ch);
-}
-
+  ANNOUNCE();
+  assert(mode);
 
-/* Finish the tarval currently under construction and give id mode `m'.
-   `m' must be irm_Bu,
-   Return NULL if the value does not make sense for this mode, this
-   can only happen in mode C.  */
-tarval *
-tarval_finish_as (ir_mode *m)
-{
-  int size = obstack_object_size (&tv_obst) - sizeof (tarval);
-  tarval *tv;
-  unsigned char *p;
-  char ch = 0;                 /* initialized to shut up gcc */
-
-  assert (BUILDING && (size >= 0));
-  if (m == mode_Bu) {
-    if (size != 1) return tarval_cancel();
-    p = (unsigned char *)obstack_base (&tv_obst) + sizeof (tarval);
-    ch = *p;
-    obstack_blank (&tv_obst, -size);
+  if (get_mode_sort(mode) == float_number) {
+    fc_get_inf();
+    return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
   }
-  tv = obstack_finish (&tv_obst);
-  p = (unsigned char *)tv + sizeof (tarval);
-  tv->mode = m;
-
-  switch (get_mode_modecode(m)) {
-  case irm_Bu:
-    tv->u.uInt = ch;
-    break;
-  case irm_P:
-    tv->u.P.tv = NULL;
-    break;
-  default:
-    assert (0);
+  else {
+    assert(0 && "tarval is not floating point");
+    return tarval_bad;
   }
-
-  return tarval_identify (tv);
 }
 
+/*
+ * Arithmethic operations on tarvals ========================================
+ */
 
-/* Cancel tarval building and return tarval_bad.  */
-tarval *
-tarval_cancel (void)
+/* test if negative number, 1 means 'yes' */
+int tarval_is_negative(tarval *a)
 {
-  assert (BUILDING);
-  obstack_free (&tv_obst, obstack_finish (&tv_obst));
-  return tarval_bad;
-}
+  ANNOUNCE();
+  assert(a);
 
+  switch (get_mode_sort(a->mode))
+  {
+    case 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;
 
-/*** ****************** Arithmethic operations on tarvals ***************** ***/
+    case float_number:
+      return fc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0;
 
-/* Return `src' converted to mode `m' if representable, else NULL.
-   @@@ lots of conversions missing */
-tarval *
-tarval_convert_to (tarval *src, ir_mode *m)
+    default:
+      assert(0 && "not implemented");
+      return 0;
+  }
+}
+
+/* comparison */
+pnc_number tarval_cmp(tarval *a, tarval *b)
 {
-  tarval *tv;
+  ANNOUNCE();
+  assert(a);
+  assert(b);
 
-  if (m == src->mode) return src;
+  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 Uo;
 
-  tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
-  tv->mode = m;
+  /* Here the two tarvals are unequal and of the same mode */
+  switch (get_mode_sort(a->mode))
+  {
+    case auxiliary:
+      return False;
 
-  switch (get_mode_modecode(src->mode)) {
+    case float_number:
+      return (fc_comp(a->value, b->value)==1)?(Gt):(Lt);
 
-  case irm_D:
-    if (m != mode_F) goto fail;
-    tv->u.F = src->u.D;
-    break;
+    case int_number:
+    case character:
+      return (sc_comp(a->value, b->value)==1)?(Gt):(Lt);
 
-  case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
-    switch (get_mode_modecode(m)) {
-    case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
-      tv->u.sInt = src->u.sInt;
-      if (sInt_overflow (tv->u.sInt, m)) goto fail;
-      break;
+    case internal_boolean:
+      return (a == tarval_b_true)?(Gt):(Lt);
 
-    case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
-      tv->u.uInt = src->u.sInt;
-      if (uInt_overflow (tv->u.uInt, m)) goto fail;
-      break;
+    case reference:
+      return Uo;
+  }
+  return False;
+}
 
-    case irm_b:
-      tv->u.b = !!src->u.sInt;
-      break;
+tarval *tarval_convert_to(tarval *src, ir_mode *m)
+{
+  ANNOUNCE();
+  tarval tv;
 
-    default: goto fail;
-    }
+  assert(src);
+  assert(m);
 
-  case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
-    switch (get_mode_modecode(m)) {
-    case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
-      tv->u.sInt = src->u.uInt;
-      if (sInt_overflow (tv->u.sInt, m)) goto fail;
-      break;
+  if (src->mode == m) return src;
 
-    case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
-      tv->u.uInt = src->u.uInt;
-      if (uInt_overflow (tv->u.uInt, m)) goto fail;
+  switch (get_mode_sort(src->mode))
+  {
+    case auxiliary:
       break;
 
-    case irm_b:
-      tv->u.b = !!src->u.uInt;
+    case float_number:
       break;
 
-    default: goto fail;
-    }
-    break;
-
-  case irm_b:
-    switch (get_mode_modecode(m)) {
-    case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
-      tv->u.sInt = src->u.b;
+    case int_number:
+      switch (get_mode_sort(m))
+      {
+        case int_number:
+        case character:
+          tv.mode = m;
+          tv.length = src->length;
+          tv.value = src->value;
+          if (overflows(&tv))
+          {
+            return tarval_bad;
+          }
+          return INSERT_TARVAL(&tv);
+
+        case internal_boolean:
+          /* XXX C semantics */
+          if (src == get_mode_null(src->mode)) return tarval_b_false;
+          else return tarval_b_true;
+
+        default:
+          break;
+      }
       break;
 
-    case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
-      tv->u.uInt = src->u.b;
+    case internal_boolean:
+      switch (get_mode_sort(m))
+      {
+        case int_number:
+          if (src == tarval_b_true) return get_mode_one(m);
+          else return get_mode_null(m);
 
-    default: goto fail;
-    }
-    break;
+        default:
+          break;
+      }
+      break;
 
-  default:
-  fail:
-    obstack_free (&tv_obst, tv);
-    return NULL;
+    case character:
+      break;
+    case reference:
+      break;
   }
 
-  return tarval_identify (tv);
+  return tarval_bad;
 }
 
-
-/* GL Why are there no ArmRoq comments, why is this not used? */
-tarval *
-tarval_neg (tarval *a)
+tarval *tarval_neg(tarval *a)              /* negation */
 {
-  tarval *tv;
-
-  TARVAL_VRFY (a);
-
-  tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
-
-  tv->mode = a->mode;
-
-  switch (get_mode_modecode(a->mode)) {
-    /* floating */
-  case irm_F: tv->u.F = -a->u.F; break;
-  case irm_D: tv->u.D = -a->u.D; break;
-    /* unsigned */
-  case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
-    tv->u.uInt = -a->u.uInt & tv_val_uInt (get_mode_max(a->mode));
-    break;
-    /* signed */
-  case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
-    tv->u.sInt = -a->u.sInt;
-    if (   sInt_overflow (tv->u.sInt, a->mode)
-       || ((tv->u.sInt >= 0) == (a->u.sInt >= 0))) {
-      obstack_free (&tv_obst, tv);
-      return NULL;
-    }
-    break;
-  case irm_b: tv->u.b = !a->u.b; break;
-  default: assert(0);
+  ANNOUNCE();
+  assert(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 */
+
+printf("NEG\n");
+  switch (get_mode_sort(a->mode))
+  {
+    case int_number:
+      sc_neg(a->value);
+      return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
+
+    case float_number:
+printf("FP NEG\n");
+      fc_neg(a->value);
+      return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode);
+
+    default:
+      return tarval_bad;
   }
-
-  return tarval_identify (tv);
 }
 
-
-/* Compare `a' with `b'.
-   Return one of irpn_Lt, irpn_Eq, irpn_Gt, irpn_Uo, or irpn_False if
-   result is unknown.  */
-ir_pncmp
-tarval_comp (tarval *a, tarval *b)
+tarval *tarval_add(tarval *a, tarval *b)   /* addition */
 {
-
-  TARVAL_VRFY (a);
-  TARVAL_VRFY (b);
-
-  assert (a->mode == b->mode);
-
-  switch (get_mode_modecode(a->mode)) {
-    /* floating */
-  case irm_F: return (  a->u.F == b->u.F ? irpn_Eq
-                     : a->u.F > b->u.F ? irpn_Gt
-                     : a->u.F < b->u.F ? irpn_Lt
-                     : irpn_Uo);
-  case irm_D: return (  a->u.D == b->u.D ? irpn_Eq
-                     : a->u.D > b->u.D ? irpn_Gt
-                     : a->u.D < b->u.D ? irpn_Lt
-                     : irpn_Uo);
-  case irm_E: return (  a->u.E == b-> u.E ? irpn_Eq
-              : a->u.E > b->u.E ? irpn_Gt
-              : a->u.E < b->u.E ? irpn_Lt
-              : irpn_Uo);
-    /* unsigned */
-  case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
-    return (  a->u.uInt == b->u.uInt ? irpn_Eq
-           : a->u.uInt > b->u.uInt ? irpn_Gt
-           : irpn_Lt);
-    /* signed */
-  case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
-    return (  a->u.sInt == b->u.sInt ? irpn_Eq
-           : a->u.sInt > b->u.sInt ? irpn_Gt
-           : irpn_Lt);
-  case irm_b: return (  a->u.b == b->u.b ? irpn_Eq
-                     : a->u.b > b->u.b ? irpn_Gt
-                     : irpn_Lt);
-  /* The following assumes that pointers are unsigned, which is valid
-     for all sane CPUs (transputers are insane). */
-  case irm_P: return (  a == b ? irpn_Eq
-                     : a == tarval_P_void ? irpn_Lt
-                     : b == tarval_P_void ? irpn_Gt
-                     : irpn_False); /* unknown */
-  default: assert (0);
+  ANNOUNCE();
+  assert(a);
+  assert(b);
+  assert((a->mode == b->mode) || (get_mode_sort(a->mode) == character && mode_is_int(b->mode)));
+
+  switch (get_mode_sort(a->mode))
+  {
+    case character:
+    case int_number:
+      /* modes of a,b are equal, so result has mode of a as this might be the character */
+      sc_add(a->value, b->value);
+      /* FIXME: Check for overflow */
+      return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
+
+    case float_number:
+      /* FIXME: Overflow/Underflow/transition to inf when mode < 80bit */
+      fc_add(a->value, b->value);
+      return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode);
+
+    default:
+      return tarval_bad;
   }
 }
 
-
-/* Return `a+b' if computable, else NULL.  Modes must be equal.  */
-tarval *
-tarval_add (tarval *a, tarval *b)
+tarval *tarval_sub(tarval *a, tarval *b)   /* subtraction */
 {
-  tarval *tv;
-
-  TARVAL_VRFY (a); TARVAL_VRFY (b);
-  assert (a->mode == b->mode);
-
-  tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
-
-  tv->mode = a->mode;
-
-  switch (get_mode_modecode(a->mode)) {
-    /* floating */
-  case irm_F: tv->u.F = a->u.F + b->u.F; break;        /* @@@ overflow etc */
-  case irm_D: tv->u.D = a->u.D + b->u.D; break; /* @@@ dto. */
-  case irm_E: tv->u.E = a->u.E + b->u.E; break; /* @@@ dto. */
-    /* unsigned */
-  case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
-    tv->u.uInt = (a->u.uInt + b->u.uInt) & tv_val_uInt (get_mode_max(a->mode));
-    break;
-    /* signed */
-  case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
-    tv->u.sInt = a->u.sInt + b->u.sInt;
-    if (   sInt_overflow (tv->u.sInt, a->mode)
-       || ((tv->u.sInt > a->u.sInt) ^ (b->u.sInt > 0))) {
-      obstack_free (&tv_obst, tv);
-      return NULL;
-    }
-    break;
-  case irm_b: tv->u.b = a->u.b | b->u.b; break;        /* u.b is in canonical form */
-  default: assert(0);
+  ANNOUNCE();
+  assert(a);
+  assert(b);
+  assert((a->mode == b->mode) || (get_mode_sort(a->mode) == character && mode_is_int(b->mode)));
+
+  switch (get_mode_sort(a->mode))
+  {
+    case character:
+    case int_number:
+      /* modes of a,b are equal, so result has mode of a as this might be the character */
+      sc_sub(a->value, b->value);
+      /* FIXME: check for overflow */
+      return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
+
+    case float_number:
+      /* FIXME: Overflow/Underflow/transition to inf when mode < 80bit */
+      fc_add(a->value, b->value);
+      return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode);
+
+    default:
+      return tarval_bad;
   }
-
-  return tarval_identify (tv);
 }
 
-
-/* Return `a-b' if computable, else NULL.  Modes must be equal.  */
-tarval *
-tarval_sub (tarval *a, tarval *b)
+tarval *tarval_mul(tarval *a, tarval *b)   /* multiplication */
 {
-  tarval *tv;
-
-  TARVAL_VRFY (a); TARVAL_VRFY (b);
-  assert (a->mode == b->mode);
-
-  tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
-
-  tv->mode = a->mode;
-
-  switch (get_mode_modecode(a->mode)) {
-    /* floating */
-  case irm_F: tv->u.F = a->u.F - b->u.F; break;        /* @@@ overflow etc */
-  case irm_D: tv->u.D = a->u.D - b->u.D; break; /* @@@ dto. */
-  case irm_E: tv->u.E = a->u.E - b->u.E; break; /* @@@ dto. */
-    /* unsigned */
-  case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
-    tv->u.uInt = (a->u.uInt - b->u.uInt) & tv_val_uInt (get_mode_max(a->mode));
-    break;
-    /* signed */
-  case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
-    tv->u.sInt = a->u.sInt - b->u.sInt;
-    if (   sInt_overflow (tv->u.sInt, a->mode)
-       || ((tv->u.sInt > a->u.sInt) ^ (b->u.sInt < 0))) {
-      obstack_free (&tv_obst, tv);
-      return NULL;
-    }
-    break;
-  case irm_b: tv->u.b = a->u.b & ~b->u.b; break; /* u.b is in canonical form */
-  default: assert(0);
+  ANNOUNCE();
+  assert(a);
+  assert(b);
+  assert((a->mode == b->mode) && mode_is_num(a->mode));
+
+  switch (get_mode_sort(a->mode))
+  {
+    case int_number:
+      /* modes of a,b are equal */
+      sc_mul(a->value, b->value);
+      /* FIXME: check for overflow */
+      return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
+
+    case float_number:
+      /* FIXME: Overflow/Underflow/transition to inf when mode < 80bit */
+      fc_add(a->value, b->value);
+      return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode);
+
+    default:
+      return tarval_bad;
   }
-
-  return tarval_identify (tv);
 }
 
-/* Return `a*b' if computable, else NULL.  Modes must be equal.  */
-tarval *
-tarval_mul (tarval *a, tarval *b)
+tarval *tarval_quo(tarval *a, tarval *b)   /* floating point division */
 {
-  tarval *tv;
-
-  TARVAL_VRFY (a); TARVAL_VRFY (b);
-  assert (a->mode == b->mode);
-
-  tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
-
-  tv->mode = a->mode;
-
-  switch (get_mode_modecode(a->mode)) {
-    /* floating */
-  case irm_F: tv->u.F = a->u.F * b->u.F; break;        /* @@@ overflow etc */
-  case irm_D: tv->u.D = a->u.D * b->u.D; break; /* @@@ dto. */
-  case irm_E: tv->u.E = a->u.E * b->u.E; break; /* @@@ dto. */
-    /* unsigned */
-  case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
-    tv->u.uInt = (a->u.uInt * b->u.uInt) & tv_val_uInt (get_mode_max(a->mode));
-    break;
-    /* signed */
-  case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
-    tv->u.sInt = a->u.sInt * b->u.sInt;
-    if (   sInt_overflow (tv->u.sInt, a->mode)
-       || (b->u.sInt && (tv->u.sInt / b->u.sInt != a->u.sInt))) {
-      obstack_free (&tv_obst, tv);
-      return NULL;
-    }
-    break;
-  case irm_b: tv->u.b = a->u.b & b->u.b; break;        /* u.b is in canonical form */
-  default: assert(0);
-  }
-
-  return tarval_identify (tv);
+  ANNOUNCE();
+  assert(a);
+  assert(b);
+  assert((a->mode == b->mode) && mode_is_float(a->mode));
+
+  /* FIXME: Overflow/Underflow/transition to inf when mode < 80bit */
+  fc_div(a->value, b->value);
+  return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode);
 }
 
-
-/* Return floating-point `a/b' if computable, else NULL.
-   Modes must be equal, non-floating-point operands are converted to irm_D.  */
-tarval *
-tarval_quo (tarval *a, tarval *b)
+tarval *tarval_div(tarval *a, tarval *b)   /* integer division */
 {
-  tarval *tv;
-
-  TARVAL_VRFY (a); TARVAL_VRFY (b);
-  assert (a->mode == b->mode);
-
-  switch (get_mode_modecode(a->mode)) {
-    /* floating */
-  case irm_F:
-    tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
-    tv->mode = mode_F;
-    tv->u.F = a->u.F / b->u.F; /* @@@ overflow etc */
-    break;
-  case irm_D:
-    tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
-    tv->mode = mode_D;
-    tv->u.D = a->u.D / b->u.D; /* @@@ overflow etc */
-    break;
-  default:
-    a = tarval_convert_to (a, mode_D);
-    b = tarval_convert_to (b, mode_D);
-    return a && b ? tarval_quo (a, b) : NULL;
-  }
-
-  return tarval_identify (tv);
+  ANNOUNCE();
+  assert(a);
+  assert(b);
+  assert((a->mode == b->mode) && mode_is_int(a->mode));
+
+  /* modes of a,b are equal */
+  sc_div(a->value, b->value);
+  return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
 }
 
+tarval *tarval_mod(tarval *a, tarval *b)   /* remainder */
+{
+  ANNOUNCE();
+  assert(a);
+  assert(b);
+  assert((a->mode == b->mode) && mode_is_int(a->mode));
+
+  /* modes of a,b are equal */
+  sc_mod(a->value, b->value);
+  return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
+}
 
-/* Return `a/b' if computable, else NULL.  Modes must be equal.  */
-tarval *
-tarval_div (tarval *a, tarval *b)
+tarval *tarval_abs(tarval *a)              /* absolute value */
 {
-  tarval *tv;
+  ANNOUNCE();
+  assert(a);
+  assert(mode_is_num(a->mode));
+
+  switch (get_mode_sort(a->mode))
+  {
+    case int_number:
+      if (sc_comp(a->value, get_mode_null(a->mode)->value) == -1)
+      {
+        sc_neg(a->value);
+        return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
+      }
+      return a;
+
+    case float_number:
+      break;
 
-  TARVAL_VRFY (a); TARVAL_VRFY (b);
-  assert (a->mode == b->mode);
-
-  tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
-
-  tv->mode = a->mode;
-
-  switch (get_mode_modecode(a->mode)) {
-    /* floating */
-  case irm_F: tv->u.F = floor (a->u.F / b->u.F); break; /* @@@ overflow etc */
-  case irm_D: tv->u.D = floor (a->u.D / b->u.D); break; /* @@@ dto. */
-  case irm_E: tv->u.E = floor (a->u.E / b->u.E); break; /* @@@ dto. */
-    /* unsigned */
-  case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
-    if (!b->u.uInt) goto fail;
-    tv->u.uInt = a->u.uInt / b->u.uInt;
-    break;
-    /* signed */
-  case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
-    if (   !b->u.sInt
-       || ((b->u.sInt == -1) && (a->u.sInt == tv_val_sInt (get_mode_max(a->mode)) ))) {
-    fail:
-      obstack_free (&tv_obst, tv);
-      return NULL;
-    }
-    tv->u.sInt = a->u.sInt / b->u.sInt;
-    break;
-  case irm_b: tv->u.b = a->u.b ^ b->u.b; break;        /* u.b is in canonical form */
-  default: assert(0);
+    default:
+      return tarval_bad;
   }
-
-  return tarval_identify (tv);
+  return tarval_bad;
 }
 
-
-/* Return `a%b' if computable, else NULL.  Modes must be equal.  */
-tarval *
-tarval_mod (tarval *a, tarval *b)
+tarval *tarval_and(tarval *a, tarval *b)   /* bitwise and */
 {
-  tarval *tv;
-
-  TARVAL_VRFY (a); TARVAL_VRFY (b);
-  assert (a->mode == b->mode);
-
-  tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
-
-  tv->mode = a->mode;
-
-  switch (get_mode_modecode(a->mode)) {
-    /* floating */
-  case irm_F: tv->u.F = fmod (a->u.F, b->u.F); break; /* @@@ overflow etc */
-  case irm_D: tv->u.D = fmod (a->u.D, b->u.D); break; /* @@@ dto */
-  case irm_E: tv->u.E = fmod (a->u.E, b->u.E); break; /* @@@ dto. */
-    /* unsigned */
-  case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
-    if (!b->u.uInt) goto fail;
-    tv->u.uInt = a->u.uInt % b->u.uInt;
-    break;
-    /* signed */
-  case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
-    if (!b->u.sInt) {
-    fail:
-      obstack_free (&tv_obst, tv);
-      return NULL;
-    }
-    tv->u.sInt = a->u.sInt % b->u.sInt;
-    break;
-  case irm_b: tv->u.b = a->u.b ^ b->u.b; break;        /* u.b is in canonical form */
-  default: assert(0);
-  }
+  ANNOUNCE();
+  assert(a);
+  assert(b);
+  assert((a->mode == b->mode) && mode_is_int(a->mode));
 
-  return tarval_identify (tv);
+  sc_and(a->value, b->value);
+  return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
 }
+tarval *tarval_or (tarval *a, tarval *b)   /* bitwise or */
+{
+  ANNOUNCE();
+  assert(a);
+  assert(b);
+  assert((a->mode == b->mode) && mode_is_int(a->mode));
 
-/* Return |a| if computable, else Null. */
-/*  is -max == min?? */
-tarval *
-tarval_abs (tarval *a) {
-  TARVAL_VRFY (a);
-  if (tv_is_negative(a)) return tarval_neg(a);
-  return a;
+  sc_or(a->value, b->value);
+  return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
 }
+tarval *tarval_eor(tarval *a, tarval *b)   /* bitwise exclusive or (xor) */
+{
+  ANNOUNCE();
+  assert(a);
+  assert(b);
+  assert((a->mode == b->mode) && mode_is_int(a->mode));
 
-int
-tv_is_negative(tarval *a) {
-  TARVAL_VRFY (a);
-  switch (get_mode_modecode(a->mode)) {
-    /* floating */
-  case irm_F: return (a->u.F<0);
-  case irm_D: return (a->u.D<0);
-  case irm_E: return (a->u.E<0);
-    /* unsigned */
-  case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
-    return 0;
-    break;
-    /* signed */
-  case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
-    return (a->u.sInt < 0);
-    break;
-  case irm_b: break;
-  default: assert(0);
-  }
-
-  return 0;
+  sc_or(a->value, b->value);
+  return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
 }
 
-
-/* Return `a&b'.  Modes must be equal.  */
-tarval *
-tarval_and (tarval *a, tarval *b)
+tarval *tarval_shl(tarval *a, tarval *b)   /* bitwise left shift */
 {
-  tarval *tv;
+  ANNOUNCE();
+  assert(a);
+  assert(b);
+  assert(mode_is_int(a->mode) && mode_is_int(b->mode));
 
-  TARVAL_VRFY (a); TARVAL_VRFY (b);
-  assert (a->mode == b->mode);
-
-  tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
-
-  tv->mode = a->mode;
-
-  switch (get_mode_modecode(a->mode)) {
-    /* unsigned */
-  case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
-    tv->u.uInt = a->u.uInt & b->u.uInt; break;
-    /* signed */
-  case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
-    tv->u.sInt = a->u.sInt & b->u.sInt; break;
-  case irm_b: tv->u.b = a->u.b & b->u.b; break;        /* u.b is in canonical form */
-  default: assert(0);
-  }
-
-  return tarval_identify (tv);
+  sc_shl(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode));
+  return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
 }
-
-
-/* Return `a|b'.  Modes must be equal.  */
-tarval *
-tarval_or (tarval *a, tarval *b)
+tarval *tarval_shr(tarval *a, tarval *b)   /* bitwise unsigned right shift */
 {
-  tarval *tv;
+  ANNOUNCE();
+  assert(a);
+  assert(b);
+  assert(mode_is_int(a->mode) && mode_is_int(b->mode));
 
-  TARVAL_VRFY (a); TARVAL_VRFY (b);
-  assert (a->mode == b->mode);
-
-  tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
-
-  tv->mode = a->mode;
-
-  switch (get_mode_modecode(a->mode)) {
-    /* unsigned */
-  case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
-    tv->u.uInt = a->u.uInt | b->u.uInt; break;
-    /* signed */
-  case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
-    tv->u.sInt = a->u.sInt | b->u.sInt; break;
-  case irm_b: tv->u.b = a->u.b | b->u.b; break;        /* u.b is in canonical form */
-  default: assert(0);
-  }
-
-  return tarval_identify (tv);
+  sc_shr(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode));
+  return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
 }
-
-
-/* Return `a^b'.  Modes must be equal.  */
-tarval *
-tarval_eor (tarval *a, tarval *b)
+tarval *tarval_shrs(tarval *a, tarval *b)  /* bitwise signed right shift */
 {
-  tarval *tv;
-
-  TARVAL_VRFY (a); TARVAL_VRFY (b);
-  assert (a->mode == b->mode);
-
-  tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
-
-  tv->mode = a->mode;
+  ANNOUNCE();
+  assert(a);
+  assert(b);
+  assert(mode_is_int(a->mode) && mode_is_int(b->mode));
 
-  switch (get_mode_modecode(a->mode)) {
-    /* unsigned */
-  case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
-    tv->u.uInt = a->u.uInt ^ b->u.uInt; break;
-    /* signed */
-  case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
-    tv->u.sInt = a->u.sInt ^ b->u.sInt; break;
-  case irm_b: tv->u.b = a->u.b ^ b->u.b; break;        /* u.b is in canonical form */
-  default: assert(0);
-  }
-
-  return tarval_identify (tv);
+  sc_shrs(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode));
+  return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
 }
+tarval *tarval_rot(tarval *a, tarval *b)   /* bitwise rotation */
+{
+  ANNOUNCE();
+  assert(a);
+  assert(b);
+  assert(mode_is_int(a->mode) && mode_is_int(b->mode));
 
+  sc_rot(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode));
+  return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
+}
 
-/* Return `a<<b' if computable, else NULL.  */
-tarval *
-tarval_shl (tarval *a, tarval *b)
+/** *********** Output of tarvals *********** **/
+int tarval_print(XP_PAR1, const xprintf_info *info ATTRIBUTE((unused)), XP_PARN)
 {
-  int b_is_huge;
-  long shift;
+  ANNOUNCE();
   tarval *tv;
+  const char *str;
+  int offset;
+  char buf[100];
+
+  tv = XP_GETARG(tarval *, 0);
+  switch (get_mode_sort(tv->mode))
+  {
+    case int_number:
+    case character:
+      offset = 16 - (get_mode_size_bits(tv->mode)/4);
+      str = sc_print_hex(tv->value);
+      return XPF1R("0x%s", str + offset);
+
+    case float_number:
+      return XPF1R("%s", fc_print_dec(tv->value, buf, sizeof(buf)));
+
+    case 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");
 
-  TARVAL_VRFY (a); TARVAL_VRFY (b);
-
-  shift = tarval_ord (b, &b_is_huge);
-  if (   b_is_huge
-      || (shift < 0)
-      || ((shift >= get_mode_size(mode_Ls)*target_bits))) {
-    return NULL;
-  }
+    case internal_boolean:
+      if (tv == tarval_b_true) return XPSR("true");
+      else return XPSR("false");
 
-  tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
-  tv->mode = a->mode;
-
-  switch (get_mode_modecode(a->mode)) {
-    /* unsigned */
-  case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
-    tv->u.uInt = a->u.uInt << shift;
-    break;
-    /* signed */
-  case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
-    tv->u.sInt = a->u.sInt << shift;
-    break;
-  default: assert (0);
+    case auxiliary:
+      return XPSR("<BAD>");
   }
 
-  return tarval_identify (tv);
+  return 0;
 }
 
-
-/* Return `a>>b' if computable, else NULL.
-   The interpretation of >> (sign extended or not) is implementaion
-   dependent, i.e. this is neither shr nor shrs!! */
-tarval *
-tarval_shr (tarval *a, tarval *b)
+char *tarval_bitpattern(tarval *tv)
 {
-  int b_is_huge;
-  long shift;
-  tarval *tv;
+  return NULL;
+}
 
-  TARVAL_VRFY (a); TARVAL_VRFY (b);
+/*
+ * access to the bitpattern
+ */
+unsigned char tarval_sub_bits(tarval *tv, unsigned byte_ofs)
+{
+  switch (get_mode_sort(tv->mode)) {
+    case int_number:
+    case character:
+      return sc_sub_bits(tv->value, tv->length, byte_ofs);
 
-  shift = tarval_ord (b, &b_is_huge);
-  if (   b_is_huge
-      || (shift < 0)
-      || ((shift >= get_mode_size(mode_Ls)*target_bits))) {
-    return NULL;
-  }
+    case float_number:
+      return fc_sub_bits(tv->value, get_mode_size_bits(tv->mode), byte_ofs);
 
-  tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
-  tv->mode = a->mode;
-
-  switch (get_mode_modecode(a->mode)) {
-    /* unsigned */
-  case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
-    tv->u.uInt = a->u.uInt >> shift;
-    break;
-    /* signed */
-  case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
-    tv->u.sInt = a->u.sInt >> shift;
-    break;
-  default: assert (0);
+    default:
+      return 0;
   }
-
-  return tarval_identify (tv);
 }
 
-
-/* Classify `tv', which may be NULL.
-   Return 0 if `tv' is the additive neutral element, 1 if `tv' is the
-   multiplicative neutral element, and -1 if `tv' is the neutral
-   element of bitwise and.  */
-long
-tarval_classify (tarval *tv)
+/* Identifying some tarvals ??? */
+/* Implemented in old tv.c as such:
+ *   return 0 for additive neutral,
+ *   1 for multiplicative neutral,
+ *   -1 for bitwise-and neutral
+ *   2 else
+ *
+ * Implemented for completeness */
+long tarval_classify(tarval *tv)
 {
-  if (!tv) return 2;
-
-  TARVAL_VRFY (tv);
-
-  switch (get_mode_modecode(tv->mode)) {
-    /* floating */
-  case irm_F: case irm_D: case irm_E:
-    return 2;
-    /* unsigned */
-  case irm_Bu:
-    return (long)((tv->u.uInt+1) & tv_val_uInt (get_mode_max(mode_Bu))) - 1;
-  case irm_Hu:
-    return (long)((tv->u.uInt+1) & tv_val_uInt (get_mode_max(mode_Hu))) - 1;
-  case irm_Iu:
-    return (long)((tv->u.uInt+1) & tv_val_uInt (get_mode_max(mode_Iu))) - 1;
-  case irm_Lu:
-    return (long)((tv->u.uInt+1) & tv_val_uInt (get_mode_max(mode_Lu))) - 1;
-    /* signed */
-  case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
-    return tv->u.sInt;
-  case irm_b:
-    return tv->u.b;
-  default:
-    return 2;
-  }
+  ANNOUNCE();
+  if (!tv || tv == tarval_bad) return 2;
+
+  if (tv == get_mode_null(tv->mode)) return 0;
+  else if (tv == get_mode_one(tv->mode)) return 1;
+  else if ((get_mode_sort(tv->mode) == int_number)
+           && (tv == new_tarval_from_long(-1, tv->mode))) return -1;
+
+  return 2;
 }
 
-/* Convert `tv' into type `long', set `fail' if not representable.
-   If `fail' gets set for an unsigned `tv', the correct result can be
-   obtained by casting the result to `unsigned long'.  */
-long
-tarval_ord (tarval *tv, int *fail)
+/* Initialization of the tarval module: called before init_mode() */
+void init_tarval_1(void)
 {
-  TARVAL_VRFY (tv);
-
-  switch (get_mode_modecode(tv->mode)) {
-    /* unsigned */
-  case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
-    *fail = tv->u.uInt > tv_val_uInt (get_mode_max(mode_Ls));
-    return tv->u.uInt;
-    /* signed */
-  case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
-    *fail = 0;
-    return tv->u.sInt;
-  case irm_b:
-    *fail = 0;
-    return tv->u.b;
-  default: ;
-    *fail = 1;
-    return 0;
-  }
+  ANNOUNCE();
+  /* initialize the sets holding the tarvals with a comparison function and
+   * an initial size, which is the expected number of constants */
+  tarvals = new_set(memcmp, TUNE_NCONSTANTS);
+  values = new_set(memcmp, TUNE_NCONSTANTS);
 }
 
-int
-tarval_print (XP_PAR1, const xprintf_info *info ATTRIBUTE((unused)), XP_PARN)
+/* Initialization of the tarval module: called after init_mode() */
+void init_tarval_2(void)
 {
-  tarval *val = XP_GETARG (tarval *, 0);
-  int printed;
-  char buf[40];
-
-  TARVAL_VRFY (val);
-
-  switch (get_mode_modecode(val->mode)) {
-
-  case irm_T:                  /* none */
-    printed = XPSR ("<bad>");
-    break;
-
-  case irm_F:                  /* float */
-    sprintf (buf, "%1.9e", (float)(val->u.F));
-    printed = XPF1R ("%s", buf);
-    break;
-  case irm_D:                  /* double */
-    printed = XPF1R ("%1.30g", (double)(val->u.D));
-    break;
-
-  case irm_C:           /* character */
-    if ((isprint (val->u.C)) &&
-       (val->u.C != '\\')   && (val->u.C != '\'')) {
-      printed = XPF1R ("'%c'", val->u.C);
-    } else {
-      printed = XPF1R ("0x%x", (unsigned long)val->u.C);
-    }
-    break;
-  case irm_U:           /* unicode character */
-      printed = XPF1R ("0x%x", (unsigned long)val->u.U);
-    break;
-
-  case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls: /* signed num */
-    printed = XPF1R ("%ld", (long)val->u.sInt);
-    break;
-  case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu: /* unsigned num */
-    printed = XPF1R ("%lu", (unsigned long)val->u.uInt);
-    break;
-
-  case irm_P:                  /* pointer */
-    if (val->u.P.xname) {
-      printed = XPR (val->u.P.xname);
-    } else if (val->u.P.ent) {
-      if (get_entity_peculiarity(val->u.P.ent) == existent)
-       printed = XPF1R ("&(%I)", get_entity_ld_ident(val->u.P.ent));
-      else
-       printed = XPSR ("(NULL)");
-    } else {
-      assert (val == tarval_P_void);
-      printed = XPSR ("(NULL)");
-    }
-    break;
-
-  case irm_b:                  /* boolean */
-    if (val->u.b) printed = XPSR ("true");
-    else         printed = XPSR ("false");
-    break;
-
-  case irm_M:                  /* memory */
-  case irm_BB:                 /* region */
-  default:
-    assert (0);
-  }
+  ANNOUNCE();
 
-  return printed;
-}
+  tarval_bad = (tarval*)malloc(sizeof(tarval));
+  tarval_bad->mode = NULL;
 
+  tarval_undefined = (tarval*)malloc(sizeof(tarval));
+  tarval_undefined->mode = NULL;
 
-ir_mode *
-get_tv_mode (tarval *tv)
-{
-  return tv->mode;
-}
+  tarval_b_true = (tarval*)malloc(sizeof(tarval));
+  tarval_b_true->mode = mode_b;
 
-/* Returns the entity if the tv is a pointer to an entity, else
-   returns NULL; */
-entity *get_tv_entity(tarval *tv) {
-  entity *ent = NULL;
+  tarval_b_false = (tarval*)malloc(sizeof(tarval));
+  tarval_b_false->mode = mode_b;
 
-  if (tv->mode == mode_P) {
-    if (tv->u.P.xname) {
-      assert(0);
-      /* not an entity */
-    } else if (tv->u.P.ent) {
-      ent = tv->u.P.ent;
-    } else {
-      /* not an entity */
-    }
-  }
-  return ent;
+  tarval_P_void = (tarval*)malloc(sizeof(tarval));
+  tarval_P_void->mode = mode_P;
 }
 
+/****************************************************************************
+ *   end of tv.c
+ ****************************************************************************/
 
 void
-free_tv_entity(entity *ent) {
+free_tarval_entity(entity *ent) {
   /* There can be a tarval referencing this entity.  Even if the
      tarval is not used by the code any more, it can still reference
      the entity as tarvals live forever (They live on an obstack.).
@@ -1448,13 +1023,6 @@ free_tv_entity(entity *ent) {
      it contains a proper entity and we will crash if the entity is
      freed.  We cannot remove tarvals from the obstack but we can
      remove the entry in the hash table. */
-  tarval *found = NULL;
-  tarval *tv = (tarval *)pset_first(tarvals);
-  while (tv) {
-    entity *tv_ent = get_tv_entity(tv);
-    if ((tv_ent) && (tv_ent == ent)) found = tv;
-    tv = pset_next(tarvals);
-  }
-  if (found)
-    pset_remove(tarvals, found, tarval_hash(found));
+  /* this will be re-implemented later */
+  ANNOUNCE();
 }