output number, not pointer
[libfirm] / ir / tv / tv.c
index 600cd93..6886f31 100644 (file)
 /* This implementation assumes:
  *  - target has IEEE-754 floating-point arithmetic.  */
 
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+
 #include <assert.h>         /* assertions */
 #include <stdlib.h>         /* atoi() */
 #include <string.h>         /* nice things for strings */
 #include <strings.h>        /* strings.h also includes bsd only function strcasecmp */
 #include <stdlib.h>
-#include <alloca.h>
+#ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+#endif
 
 #include "tv_t.h"
 #include "set.h"            /* to store tarvals in */
@@ -875,7 +883,30 @@ tarval *tarval_convert_to(tarval *src, ir_mode *m)
 }
 
 /*
- * negation
+ * bitwise negation
+ */
+tarval *tarval_not(tarval *a)
+{
+  char *buffer;
+
+  ANNOUNCE();
+  assert(a);
+  assert(mode_is_int(a->mode)); /* bitwise negation is only allowed for integer */
+
+  switch (get_mode_sort(a->mode))
+  {
+    case irms_int_number:
+      buffer = alloca(sc_get_buffer_length());
+      sc_not(a->value, buffer);
+      return get_tarval(buffer, a->length, a->mode);
+
+    default:
+      return tarval_bad;
+  }
+}
+
+/*
+ * arithmetic negation
  */
 tarval *tarval_neg(tarval *a)
 {
@@ -1143,7 +1174,7 @@ tarval *tarval_eor(tarval *a, tarval *b)
       return (a == b)? tarval_b_false : tarval_b_true;
 
     case irms_int_number:
-      sc_or(a->value, b->value, NULL);
+      sc_xor(a->value, b->value, NULL);
       return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
 
     default:
@@ -1157,12 +1188,23 @@ tarval *tarval_eor(tarval *a, tarval *b)
  */
 tarval *tarval_shl(tarval *a, tarval *b)
 {
+  char *temp_val = NULL;
   ANNOUNCE();
   assert(a);
   assert(b);
   assert(mode_is_int(a->mode) && mode_is_int(b->mode));
 
-  sc_shl(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL);
+  if (get_mode_modulo_shift(a->mode) != 0)
+  {
+    temp_val = alloca(sc_get_buffer_length());
+
+    sc_val_from_ulong(get_mode_modulo_shift(a->mode), temp_val);
+    sc_mod(b->value, temp_val, temp_val);
+  }
+  else
+    temp_val = (char*)b->value;
+
+  sc_shl(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);
 }
 
@@ -1171,11 +1213,22 @@ tarval *tarval_shl(tarval *a, tarval *b)
  */
 tarval *tarval_shr(tarval *a, tarval *b)
 {
+  char *temp_val = NULL;
   ANNOUNCE();
   assert(a);
   assert(b);
   assert(mode_is_int(a->mode) && mode_is_int(b->mode));
 
+  if (get_mode_modulo_shift(a->mode) != 0)
+  {
+    temp_val = alloca(sc_get_buffer_length());
+
+    sc_val_from_ulong(get_mode_modulo_shift(a->mode), temp_val);
+    sc_mod(b->value, temp_val, temp_val);
+  }
+  else
+    temp_val = (char*)b->value;
+
   sc_shr(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL);
   return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
 }
@@ -1185,11 +1238,22 @@ tarval *tarval_shr(tarval *a, tarval *b)
  */
 tarval *tarval_shrs(tarval *a, tarval *b)
 {
+  char *temp_val = NULL;
   ANNOUNCE();
   assert(a);
   assert(b);
   assert(mode_is_int(a->mode) && mode_is_int(b->mode));
 
+  if (get_mode_modulo_shift(a->mode) != 0)
+  {
+    temp_val = alloca(sc_get_buffer_length());
+
+    sc_val_from_ulong(get_mode_modulo_shift(a->mode), temp_val);
+    sc_mod(b->value, temp_val, temp_val);
+  }
+  else
+    temp_val = (char*)b->value;
+
   sc_shrs(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL);
   return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
 }
@@ -1199,11 +1263,22 @@ tarval *tarval_shrs(tarval *a, tarval *b)
  */
 tarval *tarval_rot(tarval *a, tarval *b)
 {
+  char *temp_val = NULL;
   ANNOUNCE();
   assert(a);
   assert(b);
   assert(mode_is_int(a->mode) && mode_is_int(b->mode));
 
+  if (get_mode_modulo_shift(a->mode) != 0)
+  {
+    temp_val = alloca(sc_get_buffer_length());
+
+    sc_val_from_ulong(get_mode_modulo_shift(a->mode), temp_val);
+    sc_mod(b->value, temp_val, temp_val);
+  }
+  else
+    temp_val = (char*)b->value;
+
   sc_rot(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL);
   return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
 }