summaryrefslogtreecommitdiffhomepage
path: root/ir/tv
diff options
context:
space:
mode:
authorMatthias Braun <matze@braunis.de>2014-12-31 01:43:41 +0100
committerMatthias Braun <matze@braunis.de>2014-12-31 06:53:59 +0100
commitde04aad30d736115ac76ed85ee6ddaf94c55879f (patch)
tree2742f9f9b36bc4c9ed7971513c799ebcc3db39bd /ir/tv
parent80b9a93ea2cd9a87b4ac61f9976e7ac39192a8f2 (diff)
fltcalc: remove the global accumulation buffer
This avoids constant testing whether an output buffer was specified or the global accumulation buffer should be used. Also remove pointless return values.
Diffstat (limited to 'ir/tv')
-rw-r--r--ir/tv/fltcalc.c202
-rw-r--r--ir/tv/fltcalc.h71
-rw-r--r--ir/tv/tv.c119
3 files changed, 160 insertions, 232 deletions
diff --git a/ir/tv/fltcalc.c b/ir/tv/fltcalc.c
index 1a0b34d..019d529 100644
--- a/ir/tv/fltcalc.c
+++ b/ir/tv/fltcalc.c
@@ -41,13 +41,10 @@ struct fp_value {
#define _exp(a) &((a)->value[0])
#define _mant(a) &((a)->value[value_size])
-/** A temporary buffer. */
-static fp_value *calc_buffer;
-
/** Current rounding mode.*/
static fc_rounding_mode_t rounding_mode;
-static unsigned calc_buffer_size;
+static unsigned fp_value_size;
static unsigned value_size;
static unsigned max_precision;
@@ -269,13 +266,13 @@ static bool handle_NAN(const fp_value *a, const fp_value *b, fp_value *result)
if (b->clss == FC_NAN && smaller_nan(b, a))
goto return_nan_b;
if (a != result)
- memcpy(result, a, calc_buffer_size);
+ memcpy(result, a, fp_value_size);
fc_exact = false;
return true;
}
if (b->clss == FC_NAN) {
return_nan_b:
- if (b != result) memcpy(result, b, calc_buffer_size);
+ if (b != result) memcpy(result, b, fp_value_size);
fc_exact = false;
return true;
}
@@ -339,14 +336,14 @@ static void _fadd(const fp_value *a, const fp_value *b, fp_value *result)
/* sign has been taken care of, check for special cases */
if (a->clss == FC_ZERO || b->clss == FC_INF) {
if (b != result)
- memcpy(result, b, calc_buffer_size);
+ memcpy(result, b, fp_value_size);
fc_exact = b->clss == FC_NORMAL;
result->sign = res_sign;
return;
}
if (b->clss == FC_ZERO || a->clss == FC_INF) {
if (a != result)
- memcpy(result, a, calc_buffer_size);
+ memcpy(result, a, fp_value_size);
fc_exact = a->clss == FC_NORMAL;
result->sign = res_sign;
return;
@@ -415,7 +412,7 @@ static void _fmul(const fp_value *a, const fp_value *b, fp_value *result)
fc_exact = false;
} else {
if (a != result)
- memcpy(result, a, calc_buffer_size);
+ memcpy(result, a, fp_value_size);
result->sign = res_sign;
}
return;
@@ -426,7 +423,7 @@ static void _fmul(const fp_value *a, const fp_value *b, fp_value *result)
fc_exact = false;
} else {
if (b != result)
- memcpy(result, b, calc_buffer_size);
+ memcpy(result, b, fp_value_size);
result->sign = res_sign;
}
return;
@@ -435,14 +432,14 @@ static void _fmul(const fp_value *a, const fp_value *b, fp_value *result)
if (a->clss == FC_INF) {
fc_exact = false;
if (a != result)
- memcpy(result, a, calc_buffer_size);
+ memcpy(result, a, fp_value_size);
result->sign = res_sign;
return;
}
if (b->clss == FC_INF) {
fc_exact = false;
if (b != result)
- memcpy(result, b, calc_buffer_size);
+ memcpy(result, b, fp_value_size);
result->sign = res_sign;
return;
}
@@ -499,7 +496,7 @@ static void _fdiv(const fp_value *a, const fp_value *b, fp_value *result)
} else {
/* 0/x -> 0 */
if (a != result)
- memcpy(result, a, calc_buffer_size);
+ memcpy(result, a, fp_value_size);
result->sign = res_sign;
}
return;
@@ -523,7 +520,7 @@ static void _fdiv(const fp_value *a, const fp_value *b, fp_value *result)
fc_exact = false;
/* inf/x -> inf */
if (a != result)
- memcpy(result, a, calc_buffer_size);
+ memcpy(result, a, fp_value_size);
result->sign = res_sign;
return;
}
@@ -600,7 +597,7 @@ static void _trunc(const fp_value *a, fp_value *result)
unsigned effective_mantissa = a->desc.mantissa_size - a->desc.explicit_one;
if (exp_val > (int)effective_mantissa) {
if (a != result)
- memcpy(result, a, calc_buffer_size);
+ memcpy(result, a, fp_value_size);
return;
}
@@ -619,33 +616,25 @@ static void _trunc(const fp_value *a, fp_value *result)
}
}
-const void *fc_get_buffer(void)
-{
- return calc_buffer;
-}
-
-unsigned fc_get_buffer_length(void)
+unsigned fc_get_value_size(void)
{
- return calc_buffer_size;
+ return fp_value_size;
}
-void *fc_val_from_str(const char *str, size_t len, void *result)
+void fc_val_from_str(const char *str, size_t len, fp_value *result)
{
char *buffer = alloca(len + 1);
memcpy(buffer, str, len);
buffer[len] = '\0';
long double val = strtold(buffer, NULL);
- return fc_val_from_ieee754(val, result);
+ fc_val_from_ieee754(val, result);
}
-fp_value *fc_val_from_bytes(fp_value *result, const unsigned char *buffer,
- const float_descriptor_t *desc)
+void fc_val_from_bytes(fp_value *result, const unsigned char *buffer,
+ const float_descriptor_t *desc)
{
- if (result == NULL)
- result = calc_buffer;
-
/* CLEAR the buffer, else some bits might be uninitialized */
- memset(result, 0, calc_buffer_size);
+ memset(result, 0, fp_value_size);
unsigned exponent_size = desc->exponent_size;
unsigned mantissa_size = desc->mantissa_size;
@@ -686,10 +675,9 @@ fp_value *fc_val_from_bytes(fp_value *result, const unsigned char *buffer,
sc_set_bit_at(_mant(result), ROUNDING_BITS+mantissa_size);
normalize(result, false);
}
- return result;
}
-fp_value *fc_val_from_ieee754(long double l, fp_value *result)
+void fc_val_from_ieee754(long double l, fp_value *result)
{
unsigned real_size
= (long_double_desc.mantissa_size+long_double_desc.exponent_size+1)/8;
@@ -701,17 +689,16 @@ fp_value *fc_val_from_ieee754(long double l, fp_value *result)
#else
memcpy(buf, &l, real_size);
#endif
- return fc_val_from_bytes(result, buf, &long_double_desc);
+ fc_val_from_bytes(result, buf, &long_double_desc);
}
long double fc_val_to_ieee754(const fp_value *val)
{
-
- fp_value *temp = (fp_value*) alloca(calc_buffer_size);
- fp_value *value = fc_cast(val, &long_double_desc, temp);
+ fp_value *temp = (fp_value*) alloca(fp_value_size);
+ fc_cast(val, &long_double_desc, temp);
sc_word *packed = ALLOCAN(sc_word, value_size);
- pack(value, packed);
+ pack(temp, packed);
char buf[sizeof(long double)];
unsigned real_size
@@ -740,11 +727,9 @@ bool fc_nan_is_quiet(const fp_value *value)
return sc_get_bit_at(_mant(value), bit);
}
-fp_value *fc_cast(const fp_value *value, const float_descriptor_t *dest,
- fp_value *result)
+void fc_cast(const fp_value *value, const float_descriptor_t *dest,
+ fp_value *result)
{
- if (result == NULL)
- result = calc_buffer;
assert(value != result);
const float_descriptor_t *desc = &value->desc;
@@ -752,15 +737,17 @@ fp_value *fc_cast(const fp_value *value, const float_descriptor_t *dest,
desc->mantissa_size == dest->mantissa_size &&
desc->explicit_one == dest->explicit_one) {
if (value != result)
- memcpy(result, value, calc_buffer_size);
- return result;
+ memcpy(result, value, fp_value_size);
+ return;
}
if (value->clss == FC_NAN) {
/* TODO: preserve mantissa bits? */
- return fc_get_nan(dest, result, !fc_nan_is_quiet(value), NULL);
+ fc_get_nan(dest, result, !fc_nan_is_quiet(value), NULL);
+ return;
} else if (value->clss == FC_INF) {
- return fc_get_inf(dest, result, value->sign);
+ fc_get_inf(dest, result, value->sign);
+ return;
}
/* set the descriptor of the new value */
@@ -789,14 +776,10 @@ fp_value *fc_cast(const fp_value *value, const float_descriptor_t *dest,
}
normalize(result, false);
- return result;
}
-fp_value *fc_get_max(const float_descriptor_t *desc, fp_value *result, bool sign)
+void fc_get_max(const float_descriptor_t *desc, fp_value *result, bool sign)
{
- if (result == NULL)
- result = calc_buffer;
-
result->desc = *desc;
result->clss = FC_NORMAL;
result->sign = sign;
@@ -804,14 +787,10 @@ fp_value *fc_get_max(const float_descriptor_t *desc, fp_value *result, bool sign
sc_val_from_ulong((1 << desc->exponent_size) - 2, _exp(result));
sc_max_from_bits(desc->mantissa_size+1-desc->explicit_one, 0, _mant(result));
sc_shlI(_mant(result), ROUNDING_BITS, _mant(result));
- return result;
}
-fp_value *fc_get_small(const float_descriptor_t *desc, fp_value *result)
+void fc_get_small(const float_descriptor_t *desc, fp_value *result)
{
- if (result == NULL)
- result = calc_buffer;
-
result->desc = *desc;
result->clss = FC_NORMAL;
result->sign = false;
@@ -819,14 +798,10 @@ fp_value *fc_get_small(const float_descriptor_t *desc, fp_value *result)
sc_zero(_mant(result));
sc_set_bit_at(_mant(result), (desc->mantissa_size - desc->explicit_one)
+ ROUNDING_BITS);
- return result;
}
-fp_value *fc_get_epsilon(const float_descriptor_t *desc, fp_value *result)
+void fc_get_epsilon(const float_descriptor_t *desc, fp_value *result)
{
- if (result == NULL)
- result = calc_buffer;
-
result->desc = *desc;
result->clss = FC_NORMAL;
result->sign = false;
@@ -836,15 +811,11 @@ fp_value *fc_get_epsilon(const float_descriptor_t *desc, fp_value *result)
sc_val_from_ulong(exp_bias - effective_mantissa, _exp(result));
sc_zero(_mant(result));
sc_set_bit_at(_mant(result), effective_mantissa + ROUNDING_BITS);
- return result;
}
-fp_value *fc_get_nan(const float_descriptor_t *desc, fp_value *result,
- bool signaling, sc_word *payload)
+void fc_get_nan(const float_descriptor_t *desc, fp_value *result,
+ bool signaling, sc_word *payload)
{
- if (result == NULL)
- result = calc_buffer;
-
result->desc = *desc;
result->clss = FC_NAN;
result->sign = 0;
@@ -877,15 +848,10 @@ fp_value *fc_get_nan(const float_descriptor_t *desc, fp_value *result,
sc_clear_bit_at(_mant(result), quiet_bit);
else
sc_set_bit_at(_mant(result), quiet_bit);
- return result;
}
-fp_value *fc_get_inf(const float_descriptor_t *desc, fp_value *result,
- bool sign)
+void fc_get_inf(const float_descriptor_t *desc, fp_value *result, bool sign)
{
- if (result == NULL)
- result = calc_buffer;
-
result->desc = *desc;
result->clss = FC_INF;
result->sign = sign;
@@ -894,7 +860,6 @@ fp_value *fc_get_inf(const float_descriptor_t *desc, fp_value *result,
// set the explicit one
sc_set_bit_at(_mant(result),
(desc->mantissa_size - desc->explicit_one)+ROUNDING_BITS);
- return result;
}
ir_relation fc_comp(fp_value const *const val_a, fp_value const *const val_b)
@@ -1080,116 +1045,85 @@ fc_rounding_mode_t fc_get_rounding_mode(void)
void init_fltcalc(unsigned precision)
{
- if (calc_buffer == NULL) {
- init_strcalc(precision + 2 + ROUNDING_BITS);
+#ifndef NDEBUG
+ static bool initialized;
+ assert(!initialized);
+ initialized = true;
+#endif
- /* needs additionally rounding bits, one bit as explicit 1., and one for
- * addition overflow */
- max_precision = sc_get_precision() - (2 + ROUNDING_BITS);
- if (max_precision < precision)
- printf("WARNING: not enough precision available, using %u\n", max_precision);
+ init_strcalc(precision + 2 + ROUNDING_BITS);
- rounding_mode = FC_TONEAREST;
- value_size = sc_get_value_length();
- calc_buffer_size = sizeof(fp_value) + 2*value_size;
+ /* needs additionally rounding bits, one bit as explicit 1., and one for
+ * addition overflow */
+ max_precision = sc_get_precision() - (2 + ROUNDING_BITS);
+ if (max_precision < precision)
+ printf("WARNING: not enough precision available, using %u\n", max_precision);
- calc_buffer = (fp_value*) xmalloc(calc_buffer_size);
- memset(calc_buffer, 0, calc_buffer_size);
+ rounding_mode = FC_TONEAREST;
+ value_size = sc_get_value_length();
+ fp_value_size = sizeof(fp_value) + 2*value_size;
#if LDBL_MANT_DIG == 64
- assert(sizeof(long double) == 12 || sizeof(long double) == 16);
- long_double_desc = (float_descriptor_t) { 15, 64, 1 };
+ assert(sizeof(long double) == 12 || sizeof(long double) == 16);
+ long_double_desc = (float_descriptor_t) { 15, 64, 1 };
#elif LDBL_MANT_DIG == 53
- assert(sizeof(long double) == 8);
- long_double_desc = (float_descriptor_t) { 11, 52, 0 };
+ assert(sizeof(long double) == 8);
+ long_double_desc = (float_descriptor_t) { 11, 52, 0 };
#else
- #error "Unsupported long double format"
+#error "Unsupported long double format"
#endif
- }
-}
-
-void finish_fltcalc(void)
-{
- free(calc_buffer);
- calc_buffer = NULL;
}
/* definition of interface functions */
-fp_value *fc_add(const fp_value *a, const fp_value *b, fp_value *result)
+void fc_add(const fp_value *a, const fp_value *b, fp_value *result)
{
- if (result == NULL)
- result = calc_buffer;
-
fc_exact = true;
if (handle_NAN(a, b, result))
- return result;
+ return;
/* make the value with the bigger exponent the first one */
if (sc_comp(_exp(a), _exp(b)) == ir_relation_less)
_fadd(b, a, result);
else
_fadd(a, b, result);
-
- return result;
}
-fp_value *fc_sub(const fp_value *a, const fp_value *b, fp_value *result)
+void fc_sub(const fp_value *a, const fp_value *b, fp_value *result)
{
- if (result == NULL)
- result = calc_buffer;
-
fc_exact = true;
if (handle_NAN(a, b, result))
- return result;
+ return;
- fp_value *temp = (fp_value*) alloca(calc_buffer_size);
- memcpy(temp, b, calc_buffer_size);
+ fp_value *temp = (fp_value*) alloca(fp_value_size);
+ memcpy(temp, b, fp_value_size);
temp->sign = !b->sign;
if (sc_comp(_exp(a), _exp(temp)) == ir_relation_less)
_fadd(temp, a, result);
else
_fadd(a, temp, result);
-
- return result;
}
-fp_value *fc_mul(const fp_value *a, const fp_value *b, fp_value *result)
+void fc_mul(const fp_value *a, const fp_value *b, fp_value *result)
{
- if (result == NULL)
- result = calc_buffer;
-
_fmul(a, b, result);
- return result;
}
-fp_value *fc_div(const fp_value *a, const fp_value *b, fp_value *result)
+void fc_div(const fp_value *a, const fp_value *b, fp_value *result)
{
- if (result == NULL)
- result = calc_buffer;
-
_fdiv(a, b, result);
- return result;
}
-fp_value *fc_neg(const fp_value *a, fp_value *result)
+void fc_neg(const fp_value *a, fp_value *result)
{
- if (result == NULL)
- result = calc_buffer;
-
if (a != result)
- memcpy(result, a, calc_buffer_size);
+ memcpy(result, a, fp_value_size);
if (result->clss != FC_NAN)
result->sign = !a->sign;
- return result;
}
-fp_value *fc_int(const fp_value *a, fp_value *result)
+void fc_int(const fp_value *a, fp_value *result)
{
- if (result == NULL)
- result = calc_buffer;
-
_trunc(a, result);
- return result;
}
flt2int_result_t fc_flt2int(const fp_value *a, sc_word *result,
diff --git a/ir/tv/fltcalc.h b/ir/tv/fltcalc.h
index ccbb4ac..15556be 100644
--- a/ir/tv/fltcalc.h
+++ b/ir/tv/fltcalc.h
@@ -45,39 +45,26 @@ typedef enum {
struct fp_value;
typedef struct fp_value fp_value;
-/** internal buffer access
- * All functions that accept NULL as return buffer put their result into an
- * internal buffer.
- * @return fc_get_buffer() returns the pointer to the buffer,
- * fc_get_buffer_length()
- * returns the size of this buffer
- */
-const void *fc_get_buffer(void);
-unsigned fc_get_buffer_length(void);
+/** Returns the size in bytes of an fp_value */
+unsigned fc_get_value_size(void);
-void *fc_val_from_str(const char *str, size_t len, void *result);
+void fc_val_from_str(const char *str, size_t len, fp_value *result);
/** get the representation of a floating point value
* This function tries to builds a representation having the same value as the
* long double floating point number passed.
*
* @param l The floating point number to build a representation for
- * @param result A buffer to hold the value built. If this is NULL, the internal
- * accumulator buffer is used. Note that the buffer must be big
- * enough to hold the value. Use fc_get_buffer_length() to find out
- * the size needed
- *
- * @return The result pointer passed to the function. If this was NULL this returns
- * a pointer to the internal accumulator buffer
+ * @param result A buffer to hold the value built.
*/
-fp_value *fc_val_from_ieee754(long double l, fp_value *result);
+void fc_val_from_ieee754(long double l, fp_value *result);
/**
* get fp_value from a floatingpoint an ieee754 float number encoded in little
* endian format in @p buffer.
*/
-fp_value *fc_val_from_bytes(fp_value *result, const unsigned char *buffer,
- const float_descriptor_t *desc);
+void fc_val_from_bytes(fp_value *result, const unsigned char *buffer,
+ const float_descriptor_t *desc);
/** retrieve the float value of an internal value
* This function casts the internal value to long double and returns a
@@ -99,14 +86,10 @@ long double fc_val_to_ieee754(const fp_value *val);
*
* @param val The value to be casted
* @param desc The floating point descriptor
- * @param result A buffer to hold the value built. If this is NULL, the internal
- * accumulator buffer is used. Note that the buffer must be big
- * enough to hold the value. Use fc_get_buffer_length() to find out
- * the size needed
- * @return The result pointer passed to the function. If this was NULL this returns
- * a pointer to the internal accumulator buffer
+ * @param result A buffer to hold the value built.
*/
-fp_value *fc_cast(const fp_value *val, const float_descriptor_t *desc, fp_value *result);
+void fc_cast(const fp_value *val, const float_descriptor_t *desc,
+ fp_value *result);
/*@{*/
/** build a special float value
@@ -114,19 +97,14 @@ fp_value *fc_cast(const fp_value *val, const float_descriptor_t *desc, fp_value
* function's suffix.
*
* @param desc The floating point descriptor
- * @param result A buffer to hold the value built. If this is NULL, the internal
- * accumulator buffer is used. Note that the buffer must be big
- * enough to hold the value. Use fc_get_buffer_length() to find out
- * the size needed
- * @return The result pointer passed to the function. If this was NULL this returns
- * a pointer to the internal accumulator buffer
- */
-fp_value *fc_get_max(const float_descriptor_t *desc, fp_value *result, bool sign);
-fp_value *fc_get_nan(const float_descriptor_t *desc, fp_value *result,
- bool signaling, sc_word *payload);
-fp_value *fc_get_inf(const float_descriptor_t *desc, fp_value *result, bool sign);
-fp_value *fc_get_small(const float_descriptor_t *desc, fp_value *result);
-fp_value *fc_get_epsilon(const float_descriptor_t *desc, fp_value *result);
+ * @param result A buffer to hold the value built.
+ */
+void fc_get_max(const float_descriptor_t *desc, fp_value *result, bool sign);
+void fc_get_nan(const float_descriptor_t *desc, fp_value *result,
+ bool signaling, sc_word *payload);
+void fc_get_inf(const float_descriptor_t *desc, fp_value *result, bool sign);
+void fc_get_small(const float_descriptor_t *desc, fp_value *result);
+void fc_get_epsilon(const float_descriptor_t *desc, fp_value *result);
/*@}*/
bool fc_is_zero(const fp_value *a);
@@ -136,12 +114,12 @@ bool fc_is_nan(const fp_value *a);
bool fc_nan_is_quiet(const fp_value *a);
bool fc_is_subnormal(const fp_value *a);
-fp_value *fc_add(const fp_value *a, const fp_value *b, fp_value *result);
-fp_value *fc_sub(const fp_value *a, const fp_value *b, fp_value *result);
-fp_value *fc_mul(const fp_value *a, const fp_value *b, fp_value *result);
-fp_value *fc_div(const fp_value *a, const fp_value *b, fp_value *result);
-fp_value *fc_neg(const fp_value *a, fp_value *result);
-fp_value *fc_int(const fp_value *a, fp_value *result);
+void fc_add(const fp_value *a, const fp_value *b, fp_value *result);
+void fc_sub(const fp_value *a, const fp_value *b, fp_value *result);
+void fc_mul(const fp_value *a, const fp_value *b, fp_value *result);
+void fc_div(const fp_value *a, const fp_value *b, fp_value *result);
+void fc_neg(const fp_value *a, fp_value *result);
+void fc_int(const fp_value *a, fp_value *result);
int fc_print(const fp_value *a, char *buf, size_t buflen, fc_base_t base);
@@ -263,6 +241,5 @@ void fc_val_to_bytes(const fp_value *val, unsigned char *buf);
bool fc_is_exact(void);
void init_fltcalc(unsigned precision);
-void finish_fltcalc(void);
#endif
diff --git a/ir/tv/tv.c b/ir/tv/tv.c
index ab24c8c..b089139 100644
--- a/ir/tv/tv.c
+++ b/ir/tv/tv.c
@@ -43,6 +43,7 @@
static struct set *tarvals = NULL;
static unsigned sc_value_length;
+static unsigned fp_value_size;
/** The integer overflow mode. */
static bool wrap_on_overflow = true;
@@ -130,12 +131,10 @@ static const float_descriptor_t *get_descriptor(const ir_mode *mode)
static ir_tarval *get_tarval_from_fp_value(const fp_value *val, ir_mode *mode)
{
- const float_descriptor_t *desc = get_descriptor(mode);
- const int buffer_length = fc_get_buffer_length();
- fp_value *tmp = alloca(buffer_length);
- memcpy(tmp, val, buffer_length);
- fp_value *casted_val = fc_cast(tmp, desc, NULL);
- return get_tarval(casted_val, buffer_length, mode);
+ const float_descriptor_t *desc = get_descriptor(mode);
+ fp_value *casted = alloca(fp_value_size);
+ fc_cast(val, desc, casted);
+ return get_tarval(casted, fp_value_size, mode);
}
ir_tarval *new_integer_tarval_from_str(const char *str, size_t len,
@@ -211,8 +210,9 @@ ir_tarval *new_tarval_from_str(const char *str, size_t len, ir_mode *mode)
return atoi(str) ? tarval_b_true : tarval_b_false;
case irms_float_number: {
- fp_value *val = fc_val_from_str(str, len, NULL);
- return get_tarval_from_fp_value(val, mode);
+ fp_value *buffer = (fp_value*)ALLOCAN(char, fp_value_size);
+ fc_val_from_str(str, len, buffer);
+ return get_tarval_from_fp_value(buffer, mode);
}
case irms_reference:
if (!strcasecmp(str, "null"))
@@ -255,7 +255,7 @@ ir_tarval *new_tarval_nan(ir_mode *mode, int signaling, ir_tarval *payload)
sc_word *sc_payload = payload != NULL ? payload->value : NULL;
assert(mode_is_float(mode));
- unsigned buffer_len = fc_get_buffer_length();
+ unsigned buffer_len = fp_value_size;
fp_value *buffer = (fp_value*)ALLOCAN(char, buffer_len);
const float_descriptor_t *desc = get_descriptor(mode);
fc_get_nan(desc, buffer, signaling, sc_payload);
@@ -275,8 +275,9 @@ ir_tarval *new_tarval_from_bytes(unsigned char const *buf,
}
case irma_ieee754:
case irma_x86_extended_float: {
- fc_val_from_bytes(NULL, buf, get_descriptor(mode));
- return get_tarval_from_fp_value(fc_get_buffer(), mode);
+ fp_value *buffer = (fp_value*)ALLOCAN(char, fp_value_size);
+ fc_val_from_bytes(buffer, buf, get_descriptor(mode));
+ return get_tarval_from_fp_value(buffer, mode);
}
case irma_none:
break;
@@ -357,8 +358,9 @@ uint64_t get_tarval_uint64(const ir_tarval *tv)
ir_tarval *new_tarval_from_long_double(long double d, ir_mode *mode)
{
assert(mode_is_float(mode));
- fp_value *val = fc_val_from_ieee754(d, NULL);
- return get_tarval_from_fp_value(val, mode);
+ fp_value *buffer = (fp_value*)ALLOCAN(char, fp_value_size);
+ fc_val_from_ieee754(d, buffer);
+ return get_tarval_from_fp_value(buffer, mode);
}
ir_tarval *new_tarval_from_double(double d, ir_mode *mode)
@@ -426,27 +428,30 @@ ir_tarval *get_tarval_small(ir_mode *mode)
{
if (!mode_is_float(mode))
panic("mode %+F does not support small value");
+ fp_value *buffer = (fp_value*)ALLOCAN(char, fp_value_size);
const float_descriptor_t *desc = get_descriptor(mode);
- fc_get_small(desc, NULL);
- return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
+ fc_get_small(desc, buffer);
+ return get_tarval(buffer, fp_value_size, mode);
}
ir_tarval *get_tarval_epsilon(ir_mode *mode)
{
if (!mode_is_float(mode))
panic("mode %+F does not support small value");
+ fp_value *buffer = (fp_value*)ALLOCAN(char, fp_value_size);
const float_descriptor_t *desc = get_descriptor(mode);
- fc_get_epsilon(desc, NULL);
- return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
+ fc_get_epsilon(desc, buffer);
+ return get_tarval(buffer, fp_value_size, mode);
}
ir_tarval *get_tarval_minus_inf(ir_mode *mode)
{
if (!mode_is_float(mode))
panic("mode %F does not support -inf value", mode);
+ fp_value *buffer = (fp_value*)ALLOCAN(char, fp_value_size);
const float_descriptor_t *desc = get_descriptor(mode);
- fc_get_inf(desc, NULL, true);
- return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
+ fc_get_inf(desc, buffer, true);
+ return get_tarval(buffer, fp_value_size, mode);
}
void init_mode_values(ir_mode* mode)
@@ -454,15 +459,14 @@ void init_mode_values(ir_mode* mode)
switch (get_mode_sort(mode)) {
case irms_float_number: {
const float_descriptor_t *desc = get_descriptor(mode);
- unsigned buflen = fc_get_buffer_length();
- fp_value *buf = alloca(buflen);
+ fp_value *buf = alloca(fp_value_size);
mode->all_one = tarval_bad;
fc_get_inf(desc, buf, false);
- mode->infinity = get_tarval(buf, buflen, mode);
+ mode->infinity = get_tarval(buf, fp_value_size, mode);
fc_get_max(desc, buf, true); // min = negative maximum
- mode->min = get_tarval(buf, buflen, mode);
+ mode->min = get_tarval(buf, fp_value_size, mode);
fc_get_max(desc, buf, false);
- mode->max = get_tarval(buf, buflen, mode);
+ mode->max = get_tarval(buf, fp_value_size, mode);
mode->null = new_tarval_from_double(0.0, mode);
mode->one = new_tarval_from_double(1.0, mode);
break;
@@ -597,15 +601,17 @@ ir_tarval *tarval_convert_to(ir_tarval *src, ir_mode *dst_mode)
switch (get_mode_sort(dst_mode)) {
case irms_float_number: {
const float_descriptor_t *desc = get_descriptor(dst_mode);
- fc_cast((const fp_value*) src->value, desc, NULL);
- return get_tarval(fc_get_buffer(), fc_get_buffer_length(), dst_mode);
+ fp_value *buffer = (fp_value*)ALLOCAN(char, fp_value_size);
+ fc_cast((const fp_value*)src->value, desc, buffer);
+ return get_tarval(buffer, fp_value_size, dst_mode);
}
case irms_int_number: {
- fp_value *res = fc_int((const fp_value*) src->value, NULL);
- sc_word *buffer = ALLOCAN(sc_word, sc_value_length);
+ fp_value *buffer = (fp_value*)ALLOCAN(char, fp_value_size);
+ fc_int((const fp_value*) src->value, buffer);
+ sc_word *intval = ALLOCAN(sc_word, sc_value_length);
flt2int_result_t cres
- = fc_flt2int(res, buffer, get_mode_size_bits(dst_mode),
+ = fc_flt2int(buffer, intval, get_mode_size_bits(dst_mode),
mode_is_signed(dst_mode));
switch (cres) {
case FLT2INT_POSITIVE_OVERFLOW:
@@ -621,7 +627,7 @@ ir_tarval *tarval_convert_to(ir_tarval *src, ir_mode *dst_mode)
case FLT2INT_BAD:
return tarval_bad;
case FLT2INT_OK:
- return get_tarval(buffer, sc_value_length, dst_mode);
+ return get_tarval(intval, sc_value_length, dst_mode);
}
}
@@ -651,10 +657,10 @@ ir_tarval *tarval_convert_to(ir_tarval *src, ir_mode *dst_mode)
* interpreted unsigned by fc_val_from_str, so this is a HACK */
int len = snprintf(buffer, 100, "%s",
sc_print(src->value, get_mode_size_bits(src->mode), SC_DEC, mode_is_signed(src->mode)));
- buffer[100 - 1] = '\0';
- fp_value *val = fc_val_from_str(buffer, len, NULL);
- return get_tarval_from_fp_value(val, dst_mode);
+ fp_value *fpval = (fp_value*)ALLOCAN(char, fp_value_size);
+ fc_val_from_str(buffer, len, fpval);
+ return get_tarval_from_fp_value(fpval, dst_mode);
}
case irms_auxiliary:
case irms_data:
@@ -739,9 +745,11 @@ ir_tarval *tarval_neg(ir_tarval *a)
return get_tarval_overflow(buffer, a->length, a->mode);
}
- case irms_float_number:
- fc_neg((const fp_value*) a->value, NULL);
- return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode);
+ case irms_float_number: {
+ fp_value *buffer = (fp_value*)ALLOCAN(char, fp_value_size);
+ fc_neg((const fp_value*)a->value, buffer);
+ return get_tarval(buffer, fp_value_size, a->mode);
+ }
case irms_auxiliary:
case irms_data:
@@ -771,9 +779,11 @@ ir_tarval *tarval_add(ir_tarval *a, ir_tarval *b)
return get_tarval_overflow(buffer, a->length, a->mode);
}
- case irms_float_number:
- fc_add((const fp_value*) a->value, (const fp_value*) b->value, NULL);
- return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode);
+ case irms_float_number: {
+ fp_value *buffer = (fp_value*)ALLOCAN(char, fp_value_size);
+ fc_add((const fp_value*)a->value, (const fp_value*)b->value, buffer);
+ return get_tarval(buffer, fp_value_size, a->mode);
+ }
case irms_auxiliary:
case irms_data:
@@ -803,9 +813,11 @@ ir_tarval *tarval_sub(ir_tarval *a, ir_tarval *b, ir_mode *dst_mode)
return get_tarval_overflow(buffer, a->length, a->mode);
}
- case irms_float_number:
- fc_sub((const fp_value*) a->value, (const fp_value*) b->value, NULL);
- return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode);
+ case irms_float_number: {
+ fp_value *buffer = (fp_value*)ALLOCAN(char, fp_value_size);
+ fc_sub((const fp_value*)a->value, (const fp_value*)b->value, buffer);
+ return get_tarval(buffer, fp_value_size, a->mode);
+ }
case irms_auxiliary:
case irms_data:
@@ -828,9 +840,11 @@ ir_tarval *tarval_mul(ir_tarval *a, ir_tarval *b)
return get_tarval_overflow(buffer, a->length, a->mode);
}
- case irms_float_number:
- fc_mul((const fp_value*) a->value, (const fp_value*) b->value, NULL);
- return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode);
+ case irms_float_number: {
+ fp_value *buffer = (fp_value*)ALLOCAN(char, fp_value_size);
+ fc_mul((const fp_value*)a->value, (const fp_value*)b->value, buffer);
+ return get_tarval(buffer, fp_value_size, a->mode);
+ }
case irms_auxiliary:
case irms_data:
@@ -857,9 +871,11 @@ ir_tarval *tarval_div(ir_tarval *a, ir_tarval *b)
return get_tarval(buffer, sc_value_length, a->mode);
}
- case irms_float_number:
- fc_div((const fp_value*) a->value, (const fp_value*) b->value, NULL);
- return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
+ case irms_float_number: {
+ fp_value *buffer = (fp_value*)ALLOCAN(char, fp_value_size);
+ fc_div((const fp_value*)a->value, (const fp_value*)b->value, buffer);
+ return get_tarval(buffer, fp_value_size, mode);
+ }
case irms_auxiliary:
case irms_data:
@@ -1244,8 +1260,9 @@ ir_tarval *ir_tarval_from_ascii(const char *buf, ir_mode *mode)
unsigned char val = hexval(buf[i*2]) | (hexval(buf[i*2+1]) << 4);
temp[i] = val;
}
- fc_val_from_bytes(NULL, temp, get_descriptor(mode));
- return get_tarval_from_fp_value(fc_get_buffer(), mode);
+ fp_value *buffer = (fp_value*)ALLOCAN(char, fp_value_size);
+ fc_val_from_bytes(buffer, temp, get_descriptor(mode));
+ return get_tarval_from_fp_value(buffer, mode);
}
case irms_data:
case irms_auxiliary:
@@ -1409,6 +1426,7 @@ void init_tarval_1(void)
init_fltcalc(128);
sc_value_length = sc_get_value_length();
+ fp_value_size = fc_get_value_size();
/* true/false must be created beforehand without mode due to a cyclic
* dependency between tarvals and modes. */
@@ -1431,7 +1449,6 @@ void init_tarval_2(void)
void finish_tarval(void)
{
finish_strcalc();
- finish_fltcalc();
del_set(tarvals); tarvals = NULL;
}