added routines to free memory
[libfirm] / ir / tv / fltcalc.h
1 /*
2  * Project:     libFIRM
3  * File name:   ir/tv/fltcalc.h
4  * Purpose:
5  * Author:
6  * Modified by:
7  * Created:     2003
8  * CVS-ID:      $Id$
9  * Copyright:   (c) 2003 Universität Karlsruhe
10  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
11  */
12
13 #ifndef _FLTCALC_H_
14 #define _FLTCALC_H_
15
16 #include "config.h"
17
18 #ifdef HAVE_LONG_DOUBLE
19 /* XXX Set this via autoconf */
20 #define HAVE_EXPLICIT_ONE
21 typedef long double LLDBL;
22 #else
23 typedef double LLDBL;
24 #endif
25
26 typedef enum {
27   FC_add,   /**< addition */
28   FC_sub,   /**< subtraction */
29   FC_mul,   /**< multiplication */
30   FC_div,   /**< divide */
31   FC_neg,   /**< negate */
32   FC_int,   /**< truncate to integer */
33   FC_rnd,   /**< round to integer */
34 } fc_op_t;
35
36 enum {
37   FC_DEC,
38   FC_HEX,
39   FC_BIN,
40   FC_PACKED,
41 };
42
43 /* rounding modes */
44 typedef enum {
45   FC_TONEAREST,
46   FC_TOPOSITIVE,
47   FC_TONEGATIVE,
48   FC_TOZERO,
49 } fc_rounding_mode_t;
50
51 #define FC_DEFAULT_PRECISION 64
52
53 #define FC_DECLARE1(code) char* fc_##code(const void *a, void *result)
54 #define FC_DECLARE2(code) char* fc_##code(const void *a, const void *b, void *result)
55
56 /*@{*/
57 /** internal buffer access
58  * All functions that accept NULL as return buffer put their result into an
59  * internal buffer.
60  * @return fc_get_buffer() returns the pointer to the buffer, fc_get_buffer_length()
61  * returns the size of this buffer
62  */
63 const void *fc_get_buffer(void);
64 const int fc_get_buffer_length(void);
65 /*}@*/
66
67 char* fc_val_from_str(const char *str, unsigned int len, char exp_size, char mant_size, char *result);
68
69 /** get the representation of a floating point value
70  * This function tries to builds a representation having the same value as the
71  * float number passed.
72  * If the wished precision is less than the precicion of LLDBL the value built
73  * will be rounded. Therefore only an approximation of the passed float can be
74  * expected in this case.
75  *
76  * @param l The floating point number to build a representation for
77  * @param exp_size The number of bits of the new exponent
78  * @param mant_size The number of bits of the new mantissa
79  * @param result A buffer to hold the value built. If this is NULL, the internal
80  *               accumulator buffer is used. Note that the buffer must be big
81  *               enough to hold the value. Use fc_get_buffer_length() to find out
82  *               the size needed
83  * @return The result pointer passed to the function. If this was NULL this returns
84  *               a pointer to the internal accumulator buffer
85  */
86 char* fc_val_from_float(LLDBL l, char exp_size, char mant_size, char *result);
87
88 /** retrieve the float value of an internal value
89  * This function casts the internal value to LLDBL and returns a LLDBL with
90  * that value.
91  * This implies that values of higher precision than LLDBL are subject to
92  * rounding, so the returned value might not the same than the actually
93  * represented value.
94  *
95  * @param val The representation of a float value
96  * @return a float value approximating the represented value
97  */
98 LLDBL fc_val_to_float(const void *val);
99
100 /** cast a value to another precision
101  * This function changes the precision of a float representation.
102  * If the new precision is less than the original precision the returned
103  * value might not be the same as the original value.
104  *
105  * @param val The value to be casted
106  * @param exp_size The number of bits of the new exponent
107  * @param mant_size The number of bits of the new mantissa
108  * @param result A buffer to hold the value built. If this is NULL, the internal
109  *               accumulator buffer is used. Note that the buffer must be big
110  *               enough to hold the value. Use fc_get_buffer_length() to find out
111  *               the size needed
112  * @return The result pointer passed to the function. If this was NULL this returns
113  *               a pointer to the internal accumulator buffer
114  */
115 char* fc_cast(const void *val, char exp_size, char mant_size, char *result);
116
117 /*@{*/
118 /** build a special float value
119  * This function builds a representation for a special float value, as indicated by the
120  * function's suffix.
121  *
122  * @param exponent_size The number of bits of exponent of the float type the value
123  *               is created for
124  * @param mantissa_size The number of bits of mantissa of the float type the value
125  *               is created for
126  * @param result A buffer to hold the value built. If this is NULL, the internal
127  *               accumulator buffer is used. Note that the buffer must be big
128  *               enough to hold the value. Use fc_get_buffer_length() to find out
129  *               the size needed
130  * @return The result pointer passed to the function. If this was NULL this returns
131  *               a pointer to the internal accumulator buffer
132  */
133 char* fc_get_min(unsigned int exponent_size, unsigned int mantissa_size, char* result);
134 char* fc_get_max(unsigned int exponent_size, unsigned int mantissa_size, char* result);
135 char* fc_get_snan(unsigned int exponent_size, unsigned int mantissa_size, char* result);
136 char* fc_get_qnan(unsigned int exponent_size, unsigned int mantissa_size, char* result);
137 char* fc_get_plusinf(unsigned int exponent_size, unsigned int mantissa_size, char* result);
138 char* fc_get_minusinf(unsigned int exponent_size, unsigned int mantissa_size, char* result);
139 /*}@*/
140
141 int fc_is_zero(const void *a);
142 int fc_is_negative(const void *a);
143 int fc_is_inf(const void *a);
144 int fc_is_nan(const void *a);
145 int fc_is_subnormal(const void *a);
146
147 FC_DECLARE2(add);
148 FC_DECLARE2(sub);
149 FC_DECLARE2(mul);
150 FC_DECLARE2(div);
151 FC_DECLARE1(neg);
152 FC_DECLARE1(int);
153 FC_DECLARE1(rnd);
154
155 char *fc_print(const void *a, char *buf, int buflen, unsigned base);
156
157 /** Compare two values
158  * This function compares two values
159  *
160  * @param a Value No. 1
161  * @param b Value No. 2
162  * @result The returned value will be one of
163  *          -1  if a < b
164  *           0  if a == b
165  *           1  if a > b
166  *           2  if either value is NaN
167  */
168 int fc_comp(const void *a, const void *b);
169
170 /** Set new rounding mode
171  * This function sets the rounding mode to one of the following, returning
172  * the previously set rounding mode.
173  * FC_TONEAREST (default):
174  *    Any unrepresentable value is rounded to the nearest representable
175  *    value. If it lies in the middle the value with the least significant
176  *    bit of zero is chosen.
177  *    Values too big to represent will round to +-infinity.
178  * FC_TONEGATIVE
179  *    Any unrepresentable value is rounded towards negative infinity.
180  *    Positive values too big to represent will round to the biggest
181  *    representable value, negative values too small to represent will
182  *    round to -infinity.
183  * FC_TOPOSITIVE
184  *    Any unrepresentable value is rounded towards positive infinity
185  *    Negative values too small to represent will round to the biggest
186  *    representable value, positive values too big to represent will
187  *    round to +infinity.
188  * FC_TOZERO
189  *    Any unrepresentable value is rounded towards zero, effectively
190  *    chopping off any bits beyond the mantissa size.
191  *    Values too big to represent will round to the biggest/smallest
192  *    representable value.
193  *
194  * These modes correspond to the modes required by the ieee standard.
195  *
196  * @param mode The new rounding mode. Any value other than the four
197  *        defined values will have no effect.
198  * @return The previous rounding mode.
199  *
200  * @see fc_get_rounding_mode()
201  * @see IEEE754, IEEE854 Floating Point Standard
202  */
203 fc_rounding_mode_t fc_set_rounding_mode(fc_rounding_mode_t mode);
204
205 /** Get the rounding mode
206  * This function retrieves the currently used rounding mode
207  *
208  * @return The current rounding mode
209  * @see fc_set_rounding_mode()
210  */
211 fc_rounding_mode_t fc_get_rounding_mode(void);
212
213 /** Get bit representation of a value
214  * This function allows to read a value in encoded form, bytewise.
215  * The value will be packed corresponding to the way used by the ieee
216  * encoding formats, i.e.
217  *        One bit   sign
218  *   exp_size bits  exponent + bias
219  *  mant_size bits  mantissa, without leading 1
220  *
221  * As in ieee, an exponent of 0 indicates a denormalized number, which
222  * implies a most significant bit of zero instead of one; an exponent
223  * of all ones (2**exp_size - 1) encodes infinity if the mantissa is
224  * all zeroes, else Not A Number.
225  *
226  * @param val A pointer to the value. If NULL is passed a copy of the
227  *        most recent value passed to this function is used, saving the
228  *        packing step. This behaviour may be changed in the future.
229  * @param num_bit The maximum number of bits to return. Any bit beyond
230  *        num_bit will be returned as zero.
231  * @param byte_ofs The byte index to read, 0 is the least significant
232  *        byte.
233  * @return 8 bits of encoded data
234  */
235 unsigned char fc_sub_bits(const void *val, unsigned num_bit, unsigned byte_ofs);
236
237 void init_fltcalc(int precision);
238 void finish_fltcalc (void);
239
240 #endif /* _FLTCALC_H_ */