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