X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Ftv%2Ffltcalc.h;h=607e3d3d433d3d3350d103dbb95e4b252c02fca2;hb=e775a978fff2841e0722c47f13545b54d48b8f98;hp=75f0691f14c04e8d2772fb6a6a3b1db61a70d671;hpb=0d1dddb39fb247e15b28a74181a0bc5bb764e2ad;p=libfirm diff --git a/ir/tv/fltcalc.h b/ir/tv/fltcalc.h index 75f0691f1..607e3d3d4 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. * @@ -27,7 +27,8 @@ #ifndef FIRM_TV_FLTCALC_H #define FIRM_TV_FLTCALC_H -#include "firm_config.h" +#include +#include "firm_types.h" #ifdef HAVE_LONG_DOUBLE /* XXX Set this via autoconf */ @@ -54,7 +55,29 @@ typedef enum { #define FC_DEFAULT_PRECISION 64 -typedef struct _fp_value fp_value; +/** + * possible float states + */ +typedef enum { + NORMAL, /**< normal representation, implicit 1 */ + ZERO, /**< +/-0 */ + SUBNORMAL, /**< denormals, implicit 0 */ + INF, /**< +/-oo */ + NAN, /**< Not A Number */ +} value_class_t; + +/** + * A descriptor for an IEEE float value. + */ +typedef struct ieee_descriptor_t { + unsigned char exponent_size; /**< size of exponent in bits */ + unsigned char mantissa_size; /**< size of mantissa in bits */ + unsigned char explicit_one; /**< set if the leading one is explicit */ + unsigned char clss; /**< state of this float */ +} ieee_descriptor_t; + +struct fp_value; +typedef struct fp_value fp_value; /*@{*/ /** internal buffer access @@ -67,7 +90,7 @@ const void *fc_get_buffer(void); int fc_get_buffer_length(void); /*}@*/ -void *fc_val_from_str(const char *str, unsigned int len, char exp_size, char mant_size, void *result); +void *fc_val_from_str(const char *str, size_t len, const ieee_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 @@ -76,17 +99,17 @@ void *fc_val_from_str(const char *str, unsigned int len, char exp_size, char man * 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 + * @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(LLDBL l, char exp_size, char mant_size, fp_value *result); +fp_value *fc_val_from_ieee754(LLDBL l, const ieee_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 @@ -95,7 +118,8 @@ fp_value *fc_val_from_ieee754(LLDBL l, char exp_size, char mant_size, fp_value * * 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_ieee754(const fp_value *val); @@ -105,40 +129,36 @@ LLDBL fc_val_to_ieee754(const fp_value *val); * 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 */ -fp_value *fc_cast(const fp_value *val, char exp_size, char mant_size, fp_value *result); +fp_value *fc_cast(const fp_value *val, const ieee_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 - */ -fp_value *fc_get_min(unsigned int exponent_size, unsigned int mantissa_size, fp_value *result); -fp_value *fc_get_max(unsigned int exponent_size, unsigned int mantissa_size, fp_value *result); -fp_value *fc_get_snan(unsigned int exponent_size, unsigned int mantissa_size, fp_value *result); -fp_value *fc_get_qnan(unsigned int exponent_size, unsigned int mantissa_size, fp_value *result); -fp_value *fc_get_plusinf(unsigned int exponent_size, unsigned int mantissa_size, fp_value *result); -fp_value *fc_get_minusinf(unsigned int exponent_size, unsigned int mantissa_size, fp_value *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 ieee_descriptor_t *desc, fp_value *result); +fp_value *fc_get_max(const ieee_descriptor_t *desc, fp_value *result); +fp_value *fc_get_snan(const ieee_descriptor_t *desc, fp_value *result); +fp_value *fc_get_qnan(const ieee_descriptor_t *desc, fp_value *result); +fp_value *fc_get_plusinf(const ieee_descriptor_t *desc, fp_value *result); +fp_value *fc_get_minusinf(const ieee_descriptor_t *desc, fp_value *result); /*@}*/ int fc_is_zero(const fp_value *a); @@ -170,6 +190,11 @@ char *fc_print(const fp_value *a, char *buf, int buflen, unsigned base); */ 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 */ @@ -180,6 +205,11 @@ int fc_zero_mantissa(const fp_value *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 ieee_descriptor_t *desc); + /** Set new rounding mode * This function sets the rounding mode to one of the following, returning * the previously set rounding mode. @@ -247,6 +277,20 @@ fc_rounding_mode_t fc_get_rounding_mode(void); */ unsigned char fc_sub_bits(const fp_value *val, unsigned num_bit, unsigned byte_ofs); +/** + * Set the immediate precision for IEEE-754 results. Set this to + * 0 to get the same precision as the operands. + * For x87 compatibility, set this to 80. + * + * @return the old setting + */ +unsigned fc_set_immediate_precision(unsigned bits); + +/** + * 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);