1 /* $Id: ieee754.h,v 1.3 2006/11/16 02:54:40 fredette Exp $ */
2 
3 /* tme/ic/ieee754.h - public header file for IEEE 754 emulation */
4 
5 /*
6  * Copyright (c) 2004 Matt Fredette
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *      This product includes software developed by Matt Fredette.
20  * 4. The name of the author may not be used to endorse or promote products
21  *    derived from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
27  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 #ifndef _TME_IC_IEEE754_H
37 #define _TME_IC_IEEE754_H
38 
39 #include <tme/common.h>
40 _TME_RCSID("$Id: ieee754.h,v 1.3 2006/11/16 02:54:40 fredette Exp $");
41 
42 /* includes: */
43 #include <tme/generic/float.h>
44 #include <tme/threads.h>
45 
46 /* macros: */
47 
48 /* underflow tininess-detection modes: */
49 #define TME_IEEE754_CTL_DETECT_TININESS_AFTER_ROUNDING	(0)
50 #define TME_IEEE754_CTL_DETECT_TININESS_BEFORE_ROUNDING	(1)
51 
52 /* floating point register file formats: */
53 #define TME_IEEE754_FPREG_FORMAT_NULL		(0)
54 #define TME_IEEE754_FPREG_FORMAT_SINGLE		(1)
55 #define TME_IEEE754_FPREG_FORMAT_DOUBLE		(2)
56 #define TME_IEEE754_FPREG_FORMAT_QUAD		(4)
57 #define TME_IEEE754_FPREG_FORMAT_ENDIAN_BIG	TME_BIT(5)
58 #define TME_IEEE754_FPREG_FORMAT_ENDIAN_LITTLE	(0)
59 #define TME_IEEE754_FPREG_FORMAT_BUILTIN	TME_BIT(6)
60 
61 /* structures: */
62 
63 /* the IEEE 754 canonical NaN type: */
64 struct tme_ieee754_nan {
65   tme_uint8_t tme_ieee754_nan_sign;
66   tme_uint16_t tme_ieee754_nan_exponent;
67   union tme_value64 tme_ieee754_nan_hi;
68   union tme_value64 tme_ieee754_nan_lo;
69 };
70 
71 /* an IEEE 754 double precision constant: */
72 struct tme_ieee754_double_constant {
73 
74   /* the two 32-bit words of the double: */
75   tme_uint32_t tme_ieee754_double_constant_hi;
76   tme_uint32_t tme_ieee754_double_constant_lo;
77 };
78 
79 /* an IEEE 754 extended80 precision constant: */
80 struct tme_ieee754_extended80_constant {
81 
82   tme_uint16_t tme_ieee754_extended80_constant_sexp;
83   tme_uint32_t tme_ieee754_extended80_constant_significand_hi;
84   tme_uint32_t tme_ieee754_extended80_constant_significand_lo;
85 };
86 
87 /* an IEEE 754 quad precision constant: */
88 struct tme_ieee754_quad_constant {
89   tme_uint32_t tme_ieee754_quad_constant_hi_hi;
90   tme_uint32_t tme_ieee754_quad_constant_hi_lo;
91   tme_uint32_t tme_ieee754_quad_constant_lo_hi;
92   tme_uint32_t tme_ieee754_quad_constant_lo_lo;
93 };
94 
95 /* the IEEE 754 control: */
96 struct tme_ieee754_ctl {
97 
98   /* a private data structure: */
99   void *tme_ieee754_ctl_private;
100 
101   /* this is one of the TME_IEEE754_CTL_DETECT_TININESS_* macros,
102      describing the underflow tininess-detection mode: */
103   tme_int8_t tme_ieee754_ctl_detect_tininess;
104 
105   /* the rounding mode: */
106   tme_int8_t tme_ieee754_ctl_rounding_mode;
107 
108   /* the extended80 rounding precision: */
109   tme_int8_t tme_ieee754_ctl_extended80_rounding_precision;
110 
111   /* whether or not a value is checked for a signaling NaN when
112      converting it from one precision to another: */
113   tme_int8_t tme_ieee754_ctl_check_snan_on_conversion;
114 
115   /* the exception function: */
116   void (*tme_ieee754_ctl_exception) _TME_P((struct tme_ieee754_ctl *, tme_int8_t));
117 
118   /* any lock unlocking function: */
119   int (*tme_ieee754_ctl_lock_unlock) _TME_P((void));
120 
121   /* the default generated NaN patterns: */
122   tme_uint32_t tme_ieee754_ctl_default_nan_single;
123   union tme_value64 tme_ieee754_ctl_default_nan_double;
124   struct tme_float_ieee754_extended80 tme_ieee754_ctl_default_nan_extended80;
125   struct tme_float_ieee754_quad tme_ieee754_ctl_default_nan_quad;
126 
127   /* signaling NaN test and nonsignaling conversion: */
128   tme_int8_t (*tme_ieee754_ctl_is_snan_single) _TME_P((tme_uint32_t *));
129   tme_int8_t (*tme_ieee754_ctl_is_snan_double) _TME_P((union tme_value64 *));
130   tme_int8_t (*tme_ieee754_ctl_is_snan_extended80) _TME_P((struct tme_float_ieee754_extended80 *));
131   tme_int8_t (*tme_ieee754_ctl_is_snan_quad) _TME_P((struct tme_float_ieee754_quad *));
132 
133   /* NaN canonicalization: */
134   void (*tme_ieee754_ctl_nan_single_to_common) _TME_P((tme_uint32_t, struct tme_ieee754_nan *));
135   void (*tme_ieee754_ctl_nan_common_to_single) _TME_P((_tme_const struct tme_ieee754_nan *, tme_uint32_t *));
136   void (*tme_ieee754_ctl_nan_double_to_common) _TME_P((_tme_const union tme_value64 *, struct tme_ieee754_nan *));
137   void (*tme_ieee754_ctl_nan_common_to_double) _TME_P((_tme_const struct tme_ieee754_nan *, union tme_value64 *));
138   void (*tme_ieee754_ctl_nan_extended80_to_common) _TME_P((_tme_const struct tme_float_ieee754_extended80 *, struct tme_ieee754_nan *));
139   void (*tme_ieee754_ctl_nan_common_to_extended80) _TME_P((_tme_const struct tme_ieee754_nan *, struct tme_float_ieee754_extended80 *));
140   void (*tme_ieee754_ctl_nan_quad_to_common) _TME_P((_tme_const struct tme_float_ieee754_quad *, struct tme_ieee754_nan *));
141   void (*tme_ieee754_ctl_nan_common_to_quad) _TME_P((_tme_const struct tme_ieee754_nan *, struct tme_float_ieee754_quad *));
142 
143   /* NaN propagation: */
144   void (*tme_ieee754_ctl_nan_from_nans_single) _TME_P((struct tme_ieee754_ctl *, _tme_const tme_uint32_t *, _tme_const tme_uint32_t *, tme_uint32_t *));
145   void (*tme_ieee754_ctl_nan_from_nans_double) _TME_P((struct tme_ieee754_ctl *, _tme_const union tme_value64 *, _tme_const union tme_value64 *, union tme_value64 *));
146   void (*tme_ieee754_ctl_nan_from_nans_extended80) _TME_P((struct tme_ieee754_ctl *, _tme_const struct tme_float_ieee754_extended80 *, _tme_const struct tme_float_ieee754_extended80 *, struct tme_float_ieee754_extended80 *));
147   void (*tme_ieee754_ctl_nan_from_nans_quad) _TME_P((struct tme_ieee754_ctl *, _tme_const struct tme_float_ieee754_quad *, _tme_const struct tme_float_ieee754_quad *, struct tme_float_ieee754_quad *));
148 };
149 
150 /* include the operation sets: */
151 #ifdef _TME_IMPL
152 #include <ic/ieee754/ieee754-auto.h>
153 #include <ic/ieee754/ieee754-ops-auto.h>
154 #else
155 #include <tme/ic/ieee754-auto.h>
156 #include <tme/ic/ieee754-ops-auto.h>
157 #endif
158 
159 /* prototypes: */
160 
161 /* this looks up an operations structure: */
162 _tme_const struct tme_ieee754_ops *tme_ieee754_ops_lookup _TME_P((_tme_const char *));
163 
164 /* NaN canonicalization defaults: */
165 void tme_ieee754_default_nan_single_to_common _TME_P((tme_uint32_t, struct tme_ieee754_nan *));
166 void tme_ieee754_default_nan_common_to_single _TME_P((_tme_const struct tme_ieee754_nan *, tme_uint32_t *));
167 void tme_ieee754_default_nan_double_to_common _TME_P((_tme_const union tme_value64 *, struct tme_ieee754_nan *));
168 void tme_ieee754_default_nan_common_to_double _TME_P((_tme_const struct tme_ieee754_nan *, union tme_value64 *));
169 void tme_ieee754_default_nan_extended80_to_common _TME_P((_tme_const struct tme_float_ieee754_extended80 *, struct tme_ieee754_nan *));
170 void tme_ieee754_default_nan_common_to_extended80 _TME_P((_tme_const struct tme_ieee754_nan *, struct tme_float_ieee754_extended80 *));
171 void tme_ieee754_default_nan_quad_to_common _TME_P((_tme_const struct tme_float_ieee754_quad *, struct tme_ieee754_nan *));
172 void tme_ieee754_default_nan_common_to_quad _TME_P((_tme_const struct tme_ieee754_nan *, struct tme_float_ieee754_quad *));
173 
174 /* the native floating-point exception function: */
175 void tme_ieee754_exception_float _TME_P((int, void *));
176 
177 /* the softfloat unlock function: */
178 int tme_ieee754_unlock_softfloat _TME_P((void));
179 
180 /* for processors that manage a fundamentally single-precision
181    floating-point register file, but that allow size-aligned sets of
182    registers to combine into double- and quad-precision registers,
183    this manages the register set and converts register contents
184    between formats: */
185 void tme_ieee754_fpreg_format _TME_P((struct tme_float *, unsigned int *, unsigned int, unsigned int));
186 
187 /* globals: */
188 
189 /* this is a compliance options string: */
190 extern _tme_const char * _tme_const tme_ieee754_compliance_options;
191 
192 /* the softfloat lock: */
193 extern tme_mutex_t tme_ieee754_global_mutex;
194 
195 /* the softfloat global control: */
196 extern struct tme_ieee754_ctl *tme_ieee754_global_ctl;
197 
198 /* the softfloat global exceptions: */
199 extern tme_int8_t tme_ieee754_global_exceptions;
200 
201 /* constants: */
202 extern _tme_const tme_uint32_t tme_ieee754_single_constant_2e2ex[];
203 extern _tme_const tme_uint32_t tme_ieee754_single_constant_2e_minus_2ex[];
204 extern _tme_const tme_uint32_t tme_ieee754_single_constant_10e2ex[];
205 extern _tme_const tme_uint32_t tme_ieee754_single_constant_pi;
206 extern _tme_const tme_uint32_t tme_ieee754_single_constant_log10_2;
207 extern _tme_const tme_uint32_t tme_ieee754_single_constant_e;
208 extern _tme_const tme_uint32_t tme_ieee754_single_constant_log2_e;
209 extern _tme_const tme_uint32_t tme_ieee754_single_constant_log10_e;
210 extern _tme_const tme_uint32_t tme_ieee754_single_constant_zero;
211 extern _tme_const tme_uint32_t tme_ieee754_single_constant_ln_2;
212 extern _tme_const tme_uint32_t tme_ieee754_single_constant_ln_10;
213 extern _tme_const tme_uint32_t tme_ieee754_single_constant_one;
214 extern _tme_const tme_uint32_t tme_ieee754_single_constant_10e_minus_2ex[];
215 extern _tme_const struct tme_ieee754_double_constant tme_ieee754_double_constant_2e2ex[];
216 extern _tme_const struct tme_ieee754_double_constant tme_ieee754_double_constant_2e_minus_2ex[];
217 extern _tme_const struct tme_ieee754_double_constant tme_ieee754_double_constant_10e2ex[];
218 extern _tme_const struct tme_ieee754_double_constant tme_ieee754_double_constant_10e_minus_2ex[];
219 extern _tme_const struct tme_ieee754_double_constant tme_ieee754_double_constant_pi;
220 extern _tme_const struct tme_ieee754_double_constant tme_ieee754_double_constant_log10_2;
221 extern _tme_const struct tme_ieee754_double_constant tme_ieee754_double_constant_e;
222 extern _tme_const struct tme_ieee754_double_constant tme_ieee754_double_constant_log2_e;
223 extern _tme_const struct tme_ieee754_double_constant tme_ieee754_double_constant_log10_e;
224 extern _tme_const struct tme_ieee754_double_constant tme_ieee754_double_constant_zero;
225 extern _tme_const struct tme_ieee754_double_constant tme_ieee754_double_constant_ln_2;
226 extern _tme_const struct tme_ieee754_double_constant tme_ieee754_double_constant_ln_10;
227 extern _tme_const struct tme_ieee754_double_constant tme_ieee754_double_constant_one;
228 extern _tme_const struct tme_ieee754_extended80_constant tme_ieee754_extended80_constant_2e2ex[];
229 extern _tme_const struct tme_ieee754_extended80_constant tme_ieee754_extended80_constant_2e_minus_2ex[];
230 extern _tme_const struct tme_ieee754_extended80_constant tme_ieee754_extended80_constant_10e2ex[];
231 extern _tme_const struct tme_ieee754_extended80_constant tme_ieee754_extended80_constant_10e_minus_2ex[];
232 extern _tme_const struct tme_ieee754_extended80_constant tme_ieee754_extended80_constant_pi;
233 extern _tme_const struct tme_ieee754_extended80_constant tme_ieee754_extended80_constant_log10_2;
234 extern _tme_const struct tme_ieee754_extended80_constant tme_ieee754_extended80_constant_e;
235 extern _tme_const struct tme_ieee754_extended80_constant tme_ieee754_extended80_constant_log2_e;
236 extern _tme_const struct tme_ieee754_extended80_constant tme_ieee754_extended80_constant_log10_e;
237 extern _tme_const struct tme_ieee754_extended80_constant tme_ieee754_extended80_constant_zero;
238 extern _tme_const struct tme_ieee754_extended80_constant tme_ieee754_extended80_constant_ln_2;
239 extern _tme_const struct tme_ieee754_extended80_constant tme_ieee754_extended80_constant_ln_10;
240 extern _tme_const struct tme_ieee754_extended80_constant tme_ieee754_extended80_constant_one;
241 
242 #endif /* !_TME_IC_IEEE754_H */
243