*/
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.
*
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);
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;
}
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.
*
}
}
+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;
*/
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
*/
}
}
+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
*/