altos: Add floating point math functions from newlib
[fw/altos] / src / math / ieeefp.h
1 #ifndef _IEEE_FP_H_
2 #define _IEEE_FP_H_
3
4 #include "_ansi.h"
5
6 #include <machine/ieeefp.h>
7
8 _BEGIN_STD_C
9
10 /* FIXME FIXME FIXME:
11    Neither of __ieee_{float,double}_shape_tape seem to be used anywhere
12    except in libm/test.  If that is the case, please delete these from here.
13    If that is not the case, please insert documentation here describing why
14    they're needed.  */
15
16 #ifdef __IEEE_BIG_ENDIAN
17
18 typedef union 
19 {
20   double value;
21   struct 
22   {
23     unsigned int sign : 1;
24     unsigned int exponent: 11;
25     unsigned int fraction0:4;
26     unsigned int fraction1:16;
27     unsigned int fraction2:16;
28     unsigned int fraction3:16;
29     
30   } number;
31   struct 
32   {
33     unsigned int sign : 1;
34     unsigned int exponent: 11;
35     unsigned int quiet:1;
36     unsigned int function0:3;
37     unsigned int function1:16;
38     unsigned int function2:16;
39     unsigned int function3:16;
40   } nan;
41   struct 
42   {
43     unsigned long msw;
44     unsigned long lsw;
45   } parts;
46     long aslong[2];
47 } __ieee_double_shape_type;
48
49 #endif
50
51 #ifdef __IEEE_LITTLE_ENDIAN
52
53 typedef union 
54 {
55   double value;
56   struct 
57   {
58 #ifdef __SMALL_BITFIELDS
59     unsigned int fraction3:16;
60     unsigned int fraction2:16;
61     unsigned int fraction1:16;
62     unsigned int fraction0: 4;
63 #else
64     unsigned int fraction1:32;
65     unsigned int fraction0:20;
66 #endif
67     unsigned int exponent :11;
68     unsigned int sign     : 1;
69   } number;
70   struct 
71   {
72 #ifdef __SMALL_BITFIELDS
73     unsigned int function3:16;
74     unsigned int function2:16;
75     unsigned int function1:16;
76     unsigned int function0:3;
77 #else
78     unsigned int function1:32;
79     unsigned int function0:19;
80 #endif
81     unsigned int quiet:1;
82     unsigned int exponent: 11;
83     unsigned int sign : 1;
84   } nan;
85   struct 
86   {
87     unsigned long lsw;
88     unsigned long msw;
89   } parts;
90
91   long aslong[2];
92
93 } __ieee_double_shape_type;
94
95 #endif
96
97 #ifdef __IEEE_BIG_ENDIAN
98
99 typedef union
100 {
101   float value;
102   struct 
103   {
104     unsigned int sign : 1;
105     unsigned int exponent: 8;
106     unsigned int fraction0: 7;
107     unsigned int fraction1: 16;
108   } number;
109   struct 
110   {
111     unsigned int sign:1;
112     unsigned int exponent:8;
113     unsigned int quiet:1;
114     unsigned int function0:6;
115     unsigned int function1:16;
116   } nan;
117   long p1;
118   
119 } __ieee_float_shape_type;
120
121 #endif
122
123 #ifdef __IEEE_LITTLE_ENDIAN
124
125 typedef union
126 {
127   float value;
128   struct 
129   {
130     unsigned int fraction0: 7;
131     unsigned int fraction1: 16;
132     unsigned int exponent: 8;
133     unsigned int sign : 1;
134   } number;
135   struct 
136   {
137     unsigned int function1:16;
138     unsigned int function0:6;
139     unsigned int quiet:1;
140     unsigned int exponent:8;
141     unsigned int sign:1;
142   } nan;
143   long p1;
144   
145 } __ieee_float_shape_type;
146
147 #endif
148
149
150
151
152
153 /* FLOATING ROUNDING */
154
155 typedef int fp_rnd;
156 #define FP_RN 0         /* Round to nearest             */
157 #define FP_RM 1         /* Round down                   */
158 #define FP_RP 2         /* Round up                     */
159 #define FP_RZ 3         /* Round to zero (trunate)      */
160
161 fp_rnd _EXFUN(fpgetround,(void));
162 fp_rnd _EXFUN(fpsetround, (fp_rnd));
163
164 /* EXCEPTIONS */
165
166 typedef int fp_except;
167 #define FP_X_INV 0x10   /* Invalid operation            */
168 #define FP_X_DX  0x80   /* Divide by zero               */
169 #define FP_X_OFL 0x04   /* Overflow exception           */
170 #define FP_X_UFL 0x02   /* Underflow exception          */
171 #define FP_X_IMP 0x01   /* imprecise exception          */
172
173 fp_except _EXFUN(fpgetmask,(void));
174 fp_except _EXFUN(fpsetmask,(fp_except));
175 fp_except _EXFUN(fpgetsticky,(void));
176 fp_except _EXFUN(fpsetsticky, (fp_except));
177
178 /* INTEGER ROUNDING */
179
180 typedef int fp_rdi;
181 #define FP_RDI_TOZ 0    /* Round to Zero                */
182 #define FP_RDI_RD  1    /* Follow float mode            */
183
184 fp_rdi _EXFUN(fpgetroundtoi,(void));
185 fp_rdi _EXFUN(fpsetroundtoi,(fp_rdi));
186
187 #undef isnan
188 #undef isinf
189
190 int _EXFUN(isnan, (double));
191 int _EXFUN(isinf, (double));
192 int _EXFUN(finite, (double));
193
194
195
196 int _EXFUN(isnanf, (float));
197 int _EXFUN(isinff, (float));
198 int _EXFUN(finitef, (float));
199
200 #define __IEEE_DBL_EXPBIAS 1023
201 #define __IEEE_FLT_EXPBIAS 127
202
203 #define __IEEE_DBL_EXPLEN 11
204 #define __IEEE_FLT_EXPLEN 8
205
206
207 #define __IEEE_DBL_FRACLEN (64 - (__IEEE_DBL_EXPLEN + 1))
208 #define __IEEE_FLT_FRACLEN (32 - (__IEEE_FLT_EXPLEN + 1))
209
210 #define __IEEE_DBL_MAXPOWTWO    ((double)(1L << 32 - 2) * (1L << (32-11) - 32 + 1))
211 #define __IEEE_FLT_MAXPOWTWO    ((float)(1L << (32-8) - 1))
212
213 #define __IEEE_DBL_NAN_EXP 0x7ff
214 #define __IEEE_FLT_NAN_EXP 0xff
215
216 #ifndef __ieeefp_isnanf
217 #define __ieeefp_isnanf(x) (((*(long *)&(x) & 0x7f800000L)==0x7f800000L) && \
218                             ((*(long *)&(x) & 0x007fffffL)!=0000000000L))
219 #endif
220 #define isnanf(x)       __ieeefp_isnanf(x)
221
222 #ifndef __ieeefp_isinff
223 #define __ieeefp_isinff(x) (((*(long *)&(x) & 0x7f800000L)==0x7f800000L) && \
224                             ((*(long *)&(x) & 0x007fffffL)==0000000000L))
225 #endif
226 #define isinff(x)       __ieeefp_isinff(x)
227
228 #ifndef __ieeefp_finitef
229 #define __ieeefp_finitef(x) (((*(long *)&(x) & 0x7f800000L)!=0x7f800000L))
230 #endif
231 #define finitef(x)      __ieeefp_finitef(x)
232
233 #ifdef _DOUBLE_IS_32BITS
234 #undef __IEEE_DBL_EXPBIAS
235 #define __IEEE_DBL_EXPBIAS __IEEE_FLT_EXPBIAS
236
237 #undef __IEEE_DBL_EXPLEN
238 #define __IEEE_DBL_EXPLEN __IEEE_FLT_EXPLEN
239
240 #undef __IEEE_DBL_FRACLEN
241 #define __IEEE_DBL_FRACLEN __IEEE_FLT_FRACLEN
242
243 #undef __IEEE_DBL_MAXPOWTWO
244 #define __IEEE_DBL_MAXPOWTWO __IEEE_FLT_MAXPOWTWO
245
246 #undef __IEEE_DBL_NAN_EXP
247 #define __IEEE_DBL_NAN_EXP __IEEE_FLT_NAN_EXP
248
249 #undef __ieee_double_shape_type
250 #define __ieee_double_shape_type __ieee_float_shape_type
251
252 #endif /* _DOUBLE_IS_32BITS */
253
254 _END_STD_C
255
256 #endif /* _IEEE_FP_H_ */