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