static struct set *values = NULL; /* container for values */
static tarval_int_overflow_mode_t int_overflow_mode = TV_OVERFLOW_WRAP;
-#define no_float 0
+/** if this is set non-zero, the constant folding for floating point is OFF */
+static int no_float = 0;
/****************************************************************************
* private functions
return atoi(str) ? tarval_b_true : tarval_b_false;
case irms_float_number:
- switch(get_mode_size_bits(mode)) {
+ switch (get_mode_size_bits(mode)) {
case 32:
fc_val_from_str(str, len, 8, 23, NULL);
break;
}
return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
- case irms_reference:
- /* same as integer modes */
- case irms_int_number:
- sc_val_from_str(str, len, NULL, mode);
- return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
+ case irms_reference:
+ /* same as integer modes */
+ case irms_int_number:
+ sc_val_from_str(str, len, NULL, mode);
+ return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
}
assert(0); /* can't be reached, can it? */
/* 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:
switch (get_mode_size_bits(mode)) {
case 32:
- fc_val_from_float(d, 8, 23, NULL);
+ fc_val_from_ieee754(d, 8, 23, NULL);
break;
case 64:
- fc_val_from_float(d, 11, 52, NULL);
+ fc_val_from_ieee754(d, 11, 52, NULL);
break;
case 80:
- fc_val_from_float(d, 15, 64, NULL);
+ fc_val_from_ieee754(d, 15, 64, NULL);
break;
}
return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
long double get_tarval_double(tarval *tv) {
assert(tarval_is_double(tv));
- return fc_val_to_float(tv->value);
+ return fc_val_to_ieee754(tv->value);
}
* value.
* The functions get_mode_{Max,Min,...} return tarvals retrieved from these
* functions, but these are stored on initialization of the irmode module and
- * therefore the irmode functions should be prefered to the functions below.
+ * therefore the irmode functions should be preferred to the functions below.
*/
tarval *(get_tarval_bad)(void) {
return mode_is_signed(mode) ? new_tarval_from_double(-1.0, mode) : tarval_bad;
case irms_int_number:
- return mode_is_signed(mode) ? new_tarval_from_long(-1l, mode) : tarval_bad;
+ return new_tarval_from_long(-1l, mode);
}
return tarval_bad;
}
return pn_Cmp_False;
case irms_float_number:
- if(no_float)
+ if (no_float)
return pn_Cmp_False;
/*
* BEWARE: we cannot compare a == b here, because
unsigned char get_tarval_sub_bits(tarval *tv, unsigned byte_ofs) {
switch (get_mode_arithmetic(tv->mode)) {
case irma_twos_complement:
- return sc_sub_bits(tv->value, tv->length, byte_ofs);
+ return sc_sub_bits(tv->value, get_mode_size_bits(tv->mode), byte_ofs);
case irma_ieee754:
return fc_sub_bits(tv->value, get_mode_size_bits(tv->mode), byte_ofs);
default:
else if (tv == get_mode_one(tv->mode))
return TV_CLASSIFY_ONE;
else if ((get_mode_sort(tv->mode) == irms_int_number)
- && (tv == new_tarval_from_long(-1, tv->mode)))
+ && (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.
*/
-int is_single_bit_tarval(tarval *tv) {
+int tarval_is_single_bit(tarval *tv) {
int i, l;
int bits;
return bits;
}
+/*
+ * Returns non-zero if the mantissa of a floating point IEEE-754
+ * tarval is zero (i.e. 1.0Exxx)
+ */
+int tarval_ieee754_zero_mantissa(tarval *tv) {
+ assert(get_mode_arithmetic(tv->mode) == irma_ieee754);
+ return fc_zero_mantissa(tv->value);
+}
+
+/* Returns the exponent of a floating point IEEE-754 tarval. */
+int tarval_ieee754_get_exponent(tarval *tv) {
+ assert(get_mode_arithmetic(tv->mode) == irma_ieee754);
+ return fc_get_exponent(tv->value);
+}
+
+/* Set the immediate precision for IEEE-754 results. */
+unsigned tarval_ieee754_set_immediate_precision(unsigned bits) {
+ return fc_set_immediate_precision(bits);
+}
+
+/* Returns non-zero if the result of the last IEEE-754 operation was exact. */
+unsigned tarval_ieee754_get_exact(void) {
+ return fc_is_exact();
+}
+
/*
* Sets the overflow mode for integer operations.
*/
int_overflow_mode = ov_mode;
}
-/**
- * Get the overflow mode for integer operations.
- */
+/* Get the overflow mode for integer operations. */
tarval_int_overflow_mode_t tarval_get_integer_overflow_mode(void) {
return int_overflow_mode;
}
+/* Enable/Disable floating point constant folding. */
+int tarval_enable_fp_ops(int enable) {
+ int old = !no_float;
+
+ no_float = !enable;
+ return old;
+}
+
/**
* default mode_info for output as HEX
*/
set_tarval_mode_output_option(mode_Ls, &hex_output);
set_tarval_mode_output_option(mode_Lu, &hex_output);
set_tarval_mode_output_option(mode_P, &hex_output);
- }
+}
/* free all memory occupied by tarval. */
void finish_tarval(void) {
- finish_strcalc ();
- finish_fltcalc ();
+ finish_strcalc();
+ finish_fltcalc();
del_set(tarvals); tarvals = NULL;
del_set(values); values = NULL;
}