/*
- * Copyright (C) 1995-2007 University of Karlsruhe. All right reserved.
+ * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
*
* This file is part of libFirm.
*
* is copied into the set */
char *temp = alloca(length);
memcpy(temp, value, length);
- if(mode_is_float(mode)) {
+ if (get_mode_arithmetic(mode) == irma_twos_complement) {
sign_extend(temp, mode);
}
tv.value = INSERT_VALUE(temp, length);
case irms_reference:
/* addresses always wrap around */
temp = alloca(sc_get_buffer_length());
- sc_val_from_ulong(-1, temp);
- sc_and(temp, value, temp);
+ memcpy(temp, value, sc_get_buffer_length());
+ sc_truncate(get_mode_size_bits(mode), temp);
/* the sc_ module expects that all bits are set ... */
sign_extend(temp, mode);
return get_tarval(temp, length, mode);
return get_mode_max(mode);
case TV_OVERFLOW_WRAP:
temp = alloca(sc_get_buffer_length());
- sc_val_from_ulong(-1, temp);
- sc_and(temp, value, temp);
+ memcpy(temp, value, sc_get_buffer_length());
+ sc_truncate(get_mode_size_bits(mode), temp);
/* the sc_ module expects that all bits are set ... */
sign_extend(temp, mode);
return get_tarval(temp, length, mode);
return get_mode_min(mode);
case TV_OVERFLOW_WRAP: {
char *temp = alloca(sc_get_buffer_length());
- sc_val_from_ulong(-1, temp);
- sc_and(temp, value, temp);
+ memcpy(temp, value, sc_get_buffer_length());
+ sc_truncate(get_mode_size_bits(mode), temp);
return get_tarval(temp, length, mode);
}
case TV_OVERFLOW_BAD:
case irms_float_number:
if (SWITCH_NOINFINITY && fc_is_inf(value)) {
- return fc_is_negative(value)?get_mode_min(mode):get_mode_max(mode);
+ /* clip infinity to maximum value */
+ return fc_is_negative(value) ? get_mode_min(mode) : get_mode_max(mode);
}
if (SWITCH_NODENORMALS && fc_is_subnormal(value)) {
+ /* clip denormals to zero */
return get_mode_null(mode);
}
break;
fc_val_from_str(str, len, 11, 52, NULL);
break;
case 80:
+ case 96:
fc_val_from_str(str, len, 15, 64, NULL);
break;
+ default:
+ panic("Unsupported mode in new_tarval_from_str()");
}
return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
fc_val_from_ieee754(d, 11, 52, NULL);
break;
case 80:
+ case 96:
fc_val_from_ieee754(d, 15, 64, NULL);
break;
+ default:
+ panic("Unsupported mode in new_tarval_from_double()");
}
return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
}
fc_get_max(11, 52, NULL);
break;
case 80:
+ case 96:
fc_get_max(15, 64, NULL);
break;
+ default:
+ panic("Unsupported mode in get_tarval_max()");
}
return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
fc_get_min(11, 52, NULL);
break;
case 80:
+ case 96:
fc_get_min(15, 64, NULL);
break;
+ default:
+ panic("Unsupported mode in get_tarval_min()");
}
return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
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);
fc_get_qnan(11, 52, NULL);
break;
case 80:
+ case 96:
fc_get_qnan(15, 64, NULL);
break;
+ default:
+ panic("Unsupported mode in get_tarval_nan()");
}
return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
} else {
fc_get_plusinf(11, 52, NULL);
break;
case 80:
+ case 96:
fc_get_plusinf(15, 64, NULL);
break;
+ default:
+ panic("Unsupported mode in get_tarval_plus_inf()");
}
return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
} else {
fc_get_minusinf(11, 52, NULL);
break;
case 80:
+ case 96:
fc_get_minusinf(15, 64, NULL);
break;
+ default:
+ panic("Unsupported mode in get_tarval_minus_inf()");
}
return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
} else {
return sc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0;
case irms_float_number:
- return fc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0;
+ return fc_is_negative(a->value);
default:
assert(0 && "not implemented");
* 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_mode_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_mode_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));
+}
+
+/*
+ * test if one, 1 means 'yes'
+ */
+int tarval_is_minus_one(tarval *a) {
+ return
+ a != tarval_bad &&
+ a == get_mode_minus_one(get_tarval_mode(a));
}
/*
fc_cast(src->value, 11, 52, NULL);
break;
case 80:
+ case 96:
fc_cast(src->value, 15, 64, NULL);
break;
default:
- break;
+ panic("Unsupported mode in tarval_convert_to()");
}
return get_tarval(fc_get_buffer(), fc_get_buffer_length(), dst_mode);
assert(0);
break;
}
- if (! fc_flt2int(res, sc_get_buffer(), dst_mode))
+ buffer = alloca(sc_get_buffer_length());
+ if (! fc_flt2int(res, buffer, dst_mode))
return tarval_bad;
- return get_tarval(sc_get_buffer(), sc_get_buffer_length(), dst_mode);
+ return get_tarval(buffer, sc_get_buffer_length(), dst_mode);
default:
/* the rest can't be converted */
fc_val_from_str(buffer, 0, 11, 52, NULL);
break;
case 80:
+ case 96:
fc_val_from_str(buffer, 0, 15, 64, NULL);
break;
+ default:
+ panic("Unsupported mode in tarval_convert_to()");
}
return get_tarval(fc_get_buffer(), fc_get_buffer_length(), dst_mode);
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 (tv == get_mode_all_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.
return fc_is_exact();
}
+/* check if its the a floating point NaN */
+int tarval_is_NaN(tarval *tv) {
+ if (! mode_is_float(tv->mode))
+ return 0;
+ return fc_is_nan(tv->value);
+}
+
+/* check if its the a floating point +inf */
+int tarval_is_plus_inf(tarval *tv) {
+ if (! mode_is_float(tv->mode))
+ return 0;
+ return fc_is_inf(tv->value) && !fc_is_negative(tv->value);
+}
+
+/* check if its the a floating point -inf */
+int tarval_is_minus_inf(tarval *tv) {
+ if (! mode_is_float(tv->mode))
+ return 0;
+ return fc_is_inf(tv->value) && fc_is_negative(tv->value);
+}
+
+/* check if the tarval represents a finite value */
+int tarval_is_finite(tarval *tv) {
+ if (mode_is_float(tv->mode))
+ return !fc_is_nan(tv->value) && !fc_is_inf(tv->value);
+ return 1;
+}
+
/*
* Sets the overflow mode for integer operations.
*/