Implement and use tarval_andnot().
authorChristoph Mallon <christoph.mallon@gmx.de>
Fri, 15 Jan 2010 11:57:22 +0000 (11:57 +0000)
committerChristoph Mallon <christoph.mallon@gmx.de>
Fri, 15 Jan 2010 11:57:22 +0000 (11:57 +0000)
[r26970]

include/libfirm/tv.h
ir/ir/iropt.c
ir/tv/strcalc.c
ir/tv/strcalc.h
ir/tv/tv.c

index bdee5c4..6433d7e 100644 (file)
@@ -553,6 +553,16 @@ tarval *tarval_abs(tarval *a);
  */
 tarval *tarval_and(tarval *a, tarval *b);
 
+/**
+ * Bitwise and not of two integer tarvals.
+ *
+ * @param a  the first tarval
+ * @param b  the second tarval
+ *
+ * @return a & ~b or tarval_bad
+ */
+tarval *tarval_andnot(tarval *a, tarval *b);
+
 /**
  * Bitwise or of two integer tarvals.
  *
index 5f4c08f..03c707b 100644 (file)
@@ -4816,7 +4816,7 @@ static ir_node *transform_node_Or_bf_store(ir_node *or) {
        ir_node *new_and, *new_const, *block;
        ir_mode *mode = get_irn_mode(or);
 
-       tarval *tv1, *tv2, *tv3, *tv4, *tv, *n_tv4, *n_tv2;
+       tarval *tv1, *tv2, *tv3, *tv4, *tv;
 
        while (1) {
                get_comm_Binop_Ops(or, &and, &c1);
@@ -4865,14 +4865,12 @@ static ir_node *transform_node_Or_bf_store(ir_node *or) {
                        return or;
                }
 
-               n_tv4 = tarval_not(tv4);
-               if (tv3 != tarval_and(tv3, n_tv4)) {
+               if (tv3 != tarval_andnot(tv3, tv4)) {
                        /* bit in the or_mask is outside the and_mask */
                        return or;
                }
 
-               n_tv2 = tarval_not(tv2);
-               if (tv1 != tarval_and(tv1, n_tv2)) {
+               if (tv1 != tarval_andnot(tv1, tv2)) {
                        /* bit in the or_mask is outside the and_mask */
                        return or;
                }
index e7cbc8c..0901ef9 100644 (file)
@@ -327,6 +327,17 @@ static void do_bitand(const char *val1, const char *val2, char *buffer) {
                buffer[counter] = val1[counter] & val2[counter];
 }
 
+/**
+ * implements the bitwise AND not operation
+ */
+static void do_bitandnot(const char *val1, const char *val2, char *buffer)
+{
+       int counter;
+
+       for (counter = 0; counter < calc_buffer_size; ++counter)
+               buffer[counter] = val1[counter] & (SC_F ^ val2[counter]);
+}
+
 /**
  * returns the sign bit.
  *
@@ -1407,6 +1418,23 @@ void sc_and(const void *value1, const void *value2, void *buffer) {
        }
 }
 
+void sc_andnot(const void *value1, const void *value2, void *buffer)
+{
+       CLEAR_BUFFER(calc_buffer);
+       carry_flag = 0;
+
+       DEBUGPRINTF_COMPUTATION(("%s & ", sc_print_hex(value1)));
+       DEBUGPRINTF_COMPUTATION(("~%s -> ", sc_print_hex(value2)));
+
+       do_bitandnot(value1, value2, calc_buffer);
+
+       DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
+
+       if (buffer != NULL && buffer != calc_buffer) {
+               memcpy(buffer, calc_buffer, calc_buffer_size);
+       }
+}
+
 void sc_or(const void *value1, const void *value2, void *buffer) {
        CLEAR_BUFFER(calc_buffer);
        carry_flag = 0;
index 5ddadad..b22ac04 100644 (file)
@@ -107,6 +107,11 @@ void sc_neg(const void *value, void *buffer);
  */
 void sc_and(const void *value1, const void *value2, void *buffer);
 
+/**
+ * buffer = value1 & ~value2
+ */
+void sc_andnot(const void *value1, const void *value2, void *buffer);
+
 /**
  * buffer = value1 | value2
  */
index 3648712..30b4000 100644 (file)
@@ -1256,6 +1256,27 @@ tarval *tarval_and(tarval *a, tarval *b) {
        }
 }
 
+tarval *tarval_andnot(tarval *a, tarval *b)
+{
+       assert(a->mode == b->mode);
+
+       /* works even for vector modes */
+       carry_flag = 0;
+
+       switch (get_mode_sort(a->mode)) {
+       case irms_internal_boolean:
+               return a == tarval_b_true && b == tarval_b_false ? tarval_b_true : tarval_b_false;
+
+       case irms_int_number:
+               sc_andnot(a->value, b->value, NULL);
+               return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
+
+       default:
+               assert(0 && "operation not defined on mode");
+               return tarval_bad;
+       }
+}
+
 /*
  * bitwise or
  */