X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Ftv%2Ffltcalc.h;h=c41257ea0c6a4a4327095c49163d0d947f9a41ff;hb=c69072442cf3ca182916752eb6d976a79f8f1d4c;hp=1f5891644bc84576fd66b3e885853e053665b292;hpb=4316c00364a6ec0ac7f7aef14af3667b12f96cf3;p=libfirm diff --git a/ir/tv/fltcalc.h b/ir/tv/fltcalc.h index 1f5891644..c41257ea0 100644 --- a/ir/tv/fltcalc.h +++ b/ir/tv/fltcalc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 1995-2007 University of Karlsruhe. All right reserved. + * Copyright (C) 1995-2011 University of Karlsruhe. All right reserved. * * This file is part of libFirm. * @@ -22,48 +22,45 @@ * @brief tarval floating point calculations * @date 2003 * @author Mathias Heil - * @version $Id$ */ #ifndef FIRM_TV_FLTCALC_H #define FIRM_TV_FLTCALC_H -#include "firm_config.h" - -#ifdef HAVE_LONG_DOUBLE -/* XXX Set this via autoconf */ -#define HAVE_EXPLICIT_ONE -typedef long double LLDBL; -#else -typedef double LLDBL; -#endif - -typedef enum { - FC_add, /**< addition */ - FC_sub, /**< subtraction */ - FC_mul, /**< multiplication */ - FC_div, /**< divide */ - FC_neg, /**< negate */ - FC_int, /**< truncate to integer */ - FC_rnd /**< round to integer */ -} fc_op_t; +#include +#include "firm_types.h" +#include "irtypes.h" enum { - FC_DEC, - FC_HEX, - FC_BIN, - FC_PACKED + FC_DEC, + FC_HEX, + FC_BIN, + FC_PACKED }; /** IEEE-754 Rounding modes. */ typedef enum { - FC_TONEAREST, /**< if unsure, to the nearest even */ - FC_TOPOSITIVE, /**< to +oo */ - FC_TONEGATIVE, /**< to -oo */ - FC_TOZERO /**< to 0 */ + FC_TONEAREST, /**< if unsure, to the nearest even */ + FC_TOPOSITIVE, /**< to +oo */ + FC_TONEGATIVE, /**< to -oo */ + FC_TOZERO /**< to 0 */ } fc_rounding_mode_t; #define FC_DEFAULT_PRECISION 64 +/** + * possible float states + */ +typedef enum { + FC_NORMAL, /**< normal representation, implicit 1 */ + FC_ZERO, /**< +/-0 */ + FC_SUBNORMAL, /**< denormals, implicit 0 */ + FC_INF, /**< +/-oo */ + FC_NAN, /**< Not A Number */ +} value_class_t; + +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 @@ -75,95 +72,93 @@ const void *fc_get_buffer(void); int fc_get_buffer_length(void); /*}@*/ -char *fc_val_from_str(const char *str, unsigned int len, char exp_size, char mant_size, char *result); +void *fc_val_from_str(const char *str, size_t len, const float_descriptor_t *desc, void *result); /** get the representation of a floating point value * This function tries to builds a representation having the same value as the * float number passed. - * If the wished precision is less than the precision of LLDBL the value built - * will be rounded. Therefore only an approximation of the passed float can be - * expected in this case. - * - * @param l The floating point number to build a representation for - * @param exp_size The number of bits of the new exponent - * @param mant_size The number of bits of the new mantissa - * @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 - */ -char *fc_val_from_float(LLDBL l, char exp_size, char mant_size, char *result); + * If the wished precision is less than the precision of long double the value + * built will be rounded. Therefore only an approximation of the passed float + * can be expected in this case. + * + * @param l The floating point number to build a representation for + * @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_val_from_ieee754(long double l, const float_descriptor_t *desc, + fp_value *result); /** retrieve the float value of an internal value - * This function casts the internal value to LLDBL and returns a LLDBL with - * that value. - * This implies that values of higher precision than LLDBL are subject to + * This function casts the internal value to long double and returns a + * long double with that value. + * This implies that values of higher precision than long double are subject to * rounding, so the returned value might not the same than the actually * represented value. * - * @param val The representation of a float value + * @param val The representation of a float value + * * @return a float value approximating the represented value */ -LLDBL fc_val_to_float(const void *val); +long double fc_val_to_ieee754(const fp_value *val); /** cast a value to another precision * This function changes the precision of a float representation. * If the new precision is less than the original precision the returned * value might not be the same as the original value. * - * @param val The value to be casted - * @param exp_size The number of bits of the new exponent - * @param mant_size The number of bits of the new mantissa - * @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 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 */ -char *fc_cast(const void *val, char exp_size, char mant_size, char *result); +fp_value *fc_cast(const fp_value *val, const float_descriptor_t *desc, fp_value *result); /*@{*/ /** build a special float value * This function builds a representation for a special float value, as indicated by the * function's suffix. * - * @param exponent_size The number of bits of exponent of the float type the value - * is created for - * @param mantissa_size The number of bits of mantissa of the float type the value - * is created 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 - */ -char *fc_get_min(unsigned int exponent_size, unsigned int mantissa_size, char* result); -char *fc_get_max(unsigned int exponent_size, unsigned int mantissa_size, char* result); -char *fc_get_snan(unsigned int exponent_size, unsigned int mantissa_size, char* result); -char *fc_get_qnan(unsigned int exponent_size, unsigned int mantissa_size, char* result); -char *fc_get_plusinf(unsigned int exponent_size, unsigned int mantissa_size, char* result); -char *fc_get_minusinf(unsigned int exponent_size, unsigned int mantissa_size, char* result); + * @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_min(const float_descriptor_t *desc, fp_value *result); +fp_value *fc_get_max(const float_descriptor_t *desc, fp_value *result); +fp_value *fc_get_snan(const float_descriptor_t *desc, fp_value *result); +fp_value *fc_get_qnan(const float_descriptor_t *desc, fp_value *result); +fp_value *fc_get_plusinf(const float_descriptor_t *desc, fp_value *result); +fp_value *fc_get_minusinf(const float_descriptor_t *desc, fp_value *result); /*@}*/ -int fc_is_zero(const void *a); -int fc_is_negative(const void *a); -int fc_is_inf(const void *a); -int fc_is_nan(const void *a); -int fc_is_subnormal(const void *a); +int fc_is_zero(const fp_value *a); +int fc_is_negative(const fp_value *a); +int fc_is_inf(const fp_value *a); +int fc_is_nan(const fp_value *a); +int fc_is_subnormal(const fp_value *a); -char *fc_add(const void *a, const void *b, void *result); -char *fc_sub(const void *a, const void *b, void *result); -char *fc_mul(const void *a, const void *b, void *result); -char *fc_div(const void *a, const void *b, void *result); -char *fc_neg(const void *a, void *result); -char *fc_int(const void *a, void *result); -char *fc_rnd(const void *a, void *result); +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); +fp_value *fc_rnd(const fp_value *a, fp_value *result); -char *fc_print(const void *a, char *buf, int buflen, unsigned base); +char *fc_print(const fp_value *a, char *buf, int buflen, unsigned base); /** Compare two values * This function compares two values @@ -176,7 +171,27 @@ char *fc_print(const void *a, char *buf, int buflen, unsigned base); * 1 if a > b * 2 if either value is NaN */ -int fc_comp(const void *a, const void *b); +int fc_comp(const fp_value *a, const fp_value *b); + +/** + * Converts an floating point value into an integer value. + */ +int fc_flt2int(const fp_value *a, void *result, ir_mode *dst_mode); + +/** + * Returns non-zero if the mantissa is zero, i.e. 1.0Exxx + */ +int fc_zero_mantissa(const fp_value *value); + +/** + * Returns the exponent of a value. + */ +int fc_get_exponent(const fp_value *value); + +/** + * Return non-zero if a given value can be converted lossless into another precision. + */ +int fc_can_lossless_conv_to(const fp_value *value, const float_descriptor_t *desc); /** Set new rounding mode * This function sets the rounding mode to one of the following, returning @@ -243,7 +258,12 @@ fc_rounding_mode_t fc_get_rounding_mode(void); * byte. * @return 8 bits of encoded data */ -unsigned char fc_sub_bits(const void *val, unsigned num_bit, unsigned byte_ofs); +unsigned char fc_sub_bits(const fp_value *val, unsigned num_bit, unsigned byte_ofs); + +/** + * Returns non-zero if the result of the last operation was exact. + */ +int fc_is_exact(void); void init_fltcalc(int precision); void finish_fltcalc(void);