From 56a161cbcf6478f5eaf9713811aa670067b35b3f Mon Sep 17 00:00:00 2001 From: Christoph Mallon Date: Fri, 15 Jan 2010 11:57:22 +0000 Subject: [PATCH] Implement and use tarval_andnot(). [r26970] --- include/libfirm/tv.h | 10 ++++++++++ ir/ir/iropt.c | 8 +++----- ir/tv/strcalc.c | 28 ++++++++++++++++++++++++++++ ir/tv/strcalc.h | 5 +++++ ir/tv/tv.c | 21 +++++++++++++++++++++ 5 files changed, 67 insertions(+), 5 deletions(-) diff --git a/include/libfirm/tv.h b/include/libfirm/tv.h index bdee5c498..6433d7e91 100644 --- a/include/libfirm/tv.h +++ b/include/libfirm/tv.h @@ -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. * diff --git a/ir/ir/iropt.c b/ir/ir/iropt.c index 5f4c08f3c..03c707be0 100644 --- a/ir/ir/iropt.c +++ b/ir/ir/iropt.c @@ -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; } diff --git a/ir/tv/strcalc.c b/ir/tv/strcalc.c index e7cbc8c0a..0901ef9ad 100644 --- a/ir/tv/strcalc.c +++ b/ir/tv/strcalc.c @@ -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; diff --git a/ir/tv/strcalc.h b/ir/tv/strcalc.h index 5ddadad48..b22ac04b0 100644 --- a/ir/tv/strcalc.h +++ b/ir/tv/strcalc.h @@ -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 */ diff --git a/ir/tv/tv.c b/ir/tv/tv.c index 36487127c..30b400043 100644 --- a/ir/tv/tv.c +++ b/ir/tv/tv.c @@ -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 */ -- 2.20.1