if (length > 0) {
/* if there already is such a value, it is returned, else value
* is copied into the set */
- tv.value = INSERT_VALUE(value, length);
+ char *temp = alloca(length);
+ memcpy(temp, value, length);
+ if (get_mode_arithmetic(mode) == irma_twos_complement) {
+ sign_extend(temp, mode);
+ }
+ tv.value = INSERT_VALUE(temp, length);
} else {
tv.value = value;
}
/* same as integer modes */
case irms_int_number:
sc_val_from_long(l, NULL);
- sign_extend(sc_get_buffer(), mode);
return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
case irms_float_number:
case irms_control_flow:
case irms_memory:
case irms_auxiliary:
- case irms_internal_boolean:
assert(0);
break;
case irms_float_number:
return new_tarval_from_double(0.0, mode);
+ case irms_internal_boolean:
case irms_int_number:
return new_tarval_from_long(0l, mode);
if (get_mode_n_vector_elems(mode) > 1) {
/* vector arithmetic not implemented yet */
+ assert(0);
return tarval_bad;
}
case irms_control_flow:
case irms_memory:
case irms_auxiliary:
- case irms_internal_boolean:
- case irms_reference:
assert(0);
break;
+ case irms_internal_boolean:
+ return tarval_b_true;
+
case irms_float_number:
return new_tarval_from_double(1.0, mode);
+ case irms_reference:
case irms_int_number:
return new_tarval_from_long(1l, mode);
- break;
}
return tarval_bad;
}
-tarval *get_tarval_minus_one(ir_mode *mode) {
+tarval *get_tarval_all_one(ir_mode *mode) {
assert(mode);
if (get_mode_n_vector_elems(mode) > 1) {
/* vector arithmetic not implemented yet */
+ assert(0);
return tarval_bad;
}
case irms_control_flow:
case irms_memory:
case irms_auxiliary:
+ assert(0);
+ return tarval_bad;
+
+ case irms_int_number:
case irms_internal_boolean:
case irms_reference:
+ return tarval_not(get_mode_null(mode));
+
+
+ case irms_float_number:
+ return new_tarval_from_double(1.0, mode);
+ }
+ return tarval_bad;
+}
+
+tarval *get_tarval_minus_one(ir_mode *mode) {
+ assert(mode);
+
+ if (get_mode_n_vector_elems(mode) > 1) {
+ /* vector arithmetic not implemented yet */
+ return tarval_bad;
+ }
+
+ switch(get_mode_sort(mode)) {
+ case irms_control_flow:
+ case irms_memory:
+ case irms_auxiliary:
+ case irms_internal_boolean:
assert(0);
break;
+ case irms_reference:
+ return tarval_bad;
+
case irms_float_number:
return mode_is_signed(mode) ? new_tarval_from_double(-1.0, mode) : tarval_bad;
* test if null, 1 means 'yes'
*/
int tarval_is_null(tarval *a) {
- ir_mode *m = get_tarval_mode(a);
-
- return a == get_tarval_null(m);
+ return
+ a != tarval_bad &&
+ a == get_tarval_null(get_tarval_mode(a));
}
/*
* test if one, 1 means 'yes'
*/
int tarval_is_one(tarval *a) {
- ir_mode *m = get_tarval_mode(a);
+ return
+ a != tarval_bad &&
+ a == get_tarval_one(get_tarval_mode(a));
+}
- return a == get_tarval_one(m);
+int tarval_is_all_one(tarval *tv) {
+ return
+ tv != tarval_bad &&
+ tv == get_mode_all_one(get_tarval_mode(tv));
}
/*
/* works for vector mode without changes */
switch (get_mode_sort(a->mode)) {
+ case irms_reference:
case irms_int_number:
buffer = alloca(sc_get_buffer_length());
sc_not(a->value, buffer);
return mode->tv_priv;
}
-/*
- * Identifying tarvals values for algebraic simplifications.
- *
- * Returns:
- * - TV_CLASSIFY_NULL for additive neutral or the NULL tarval for reference modes,
- * - TV_CLASSIFY_ONE for multiplicative neutral,
- * - TV_CLASSIFY_ALL_ONE for bitwise-and neutral
- * - TV_CLASSIFY_OTHER else
- */
-tarval_classification_t classify_tarval(tarval *tv) {
- if (!tv || tv == tarval_bad) return TV_CLASSIFY_OTHER;
-
- if (tv == get_mode_null(tv->mode))
- return TV_CLASSIFY_NULL;
- else if (tv == get_mode_one(tv->mode))
- return TV_CLASSIFY_ONE;
- else if ((get_mode_sort(tv->mode) == irms_int_number)
- && (tv == get_mode_minus_one(tv->mode)))
- return TV_CLASSIFY_ALL_ONE;
-
- return TV_CLASSIFY_OTHER;
-}
-
/*
* Returns non-zero if a given (integer) tarval has only one single bit
* set.