Commit 56a161cb authored by Christoph Mallon's avatar Christoph Mallon
Browse files

Implement and use tarval_andnot().

[r26970]
parent 786de5e2
......@@ -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.
*
......
......@@ -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;
}
......
......@@ -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;
......
......@@ -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
*/
......
......@@ -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
*/
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment