1 | /* |
---|
2 | * ==================================================== |
---|
3 | * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. |
---|
4 | * |
---|
5 | * Developed at SunPro, a Sun Microsystems, Inc. business. |
---|
6 | * Permission to use, copy, modify, and distribute this |
---|
7 | * software is freely granted, provided that this notice |
---|
8 | * is preserved. |
---|
9 | * ==================================================== |
---|
10 | */ |
---|
11 | |
---|
12 | /* Modified for GIET-VM static OS at UPMC, France 2015. |
---|
13 | */ |
---|
14 | |
---|
15 | #ifndef _MATH_PRIVATE_H_ |
---|
16 | #define _MATH_PRIVATE_H_ |
---|
17 | |
---|
18 | #include <stdint.h> |
---|
19 | |
---|
20 | typedef uint32_t u_int32_t; |
---|
21 | |
---|
22 | |
---|
23 | /* The original fdlibm code used statements like: |
---|
24 | n0 = ((*(int*)&one)>>29)^1; * index of high word * |
---|
25 | ix0 = *(n0+(int*)&x); * high word of x * |
---|
26 | ix1 = *((1-n0)+(int*)&x); * low word of x * |
---|
27 | to dig two 32 bit words out of the 64 bit IEEE floating point |
---|
28 | value. That is non-ANSI, and, moreover, the gcc instruction |
---|
29 | scheduler gets it wrong. We instead use the following macros. |
---|
30 | Unlike the original code, we determine the endianness at compile |
---|
31 | time, not at run time; I don't see much benefit to selecting |
---|
32 | endianness at run time. */ |
---|
33 | |
---|
34 | /* A union which permits us to convert between a double and two 32 bit |
---|
35 | ints. */ |
---|
36 | |
---|
37 | /* |
---|
38 | * Math on arm is special (read: stupid): |
---|
39 | * For FPA, float words are always big-endian. |
---|
40 | * For VFP, float words follow the memory system mode. |
---|
41 | * For Maverick, float words are always little-endian. |
---|
42 | */ |
---|
43 | |
---|
44 | |
---|
45 | /* |
---|
46 | #if (__BYTE_ORDER == __BIG_ENDIAN) |
---|
47 | |
---|
48 | |
---|
49 | typedef union |
---|
50 | { |
---|
51 | double value; |
---|
52 | struct |
---|
53 | { |
---|
54 | u_int32_t msw; |
---|
55 | u_int32_t lsw; |
---|
56 | } parts; |
---|
57 | } ieee_double_shape_type; |
---|
58 | |
---|
59 | #else |
---|
60 | */ |
---|
61 | |
---|
62 | typedef union |
---|
63 | { |
---|
64 | double value; |
---|
65 | struct |
---|
66 | { |
---|
67 | u_int32_t lsw; |
---|
68 | u_int32_t msw; |
---|
69 | } parts; |
---|
70 | } ieee_double_shape_type; |
---|
71 | |
---|
72 | //#endif |
---|
73 | |
---|
74 | |
---|
75 | /* Get two 32 bit ints from a double. */ |
---|
76 | |
---|
77 | #define EXTRACT_WORDS(ix0,ix1,d) \ |
---|
78 | do { \ |
---|
79 | ieee_double_shape_type ew_u; \ |
---|
80 | ew_u.value = (d); \ |
---|
81 | (ix0) = ew_u.parts.msw; \ |
---|
82 | (ix1) = ew_u.parts.lsw; \ |
---|
83 | } while (0) |
---|
84 | |
---|
85 | /* Get the more significant 32 bit int from a double. */ |
---|
86 | |
---|
87 | #define GET_HIGH_WORD(i,d) \ |
---|
88 | do { \ |
---|
89 | ieee_double_shape_type gh_u; \ |
---|
90 | gh_u.value = (d); \ |
---|
91 | (i) = gh_u.parts.msw; \ |
---|
92 | } while (0) |
---|
93 | |
---|
94 | /* Get the less significant 32 bit int from a double. */ |
---|
95 | |
---|
96 | #define GET_LOW_WORD(i,d) \ |
---|
97 | do { \ |
---|
98 | ieee_double_shape_type gl_u; \ |
---|
99 | gl_u.value = (d); \ |
---|
100 | (i) = gl_u.parts.lsw; \ |
---|
101 | } while (0) |
---|
102 | |
---|
103 | /* Set a double from two 32 bit ints. */ |
---|
104 | |
---|
105 | #define INSERT_WORDS(d,ix0,ix1) \ |
---|
106 | do { \ |
---|
107 | ieee_double_shape_type iw_u; \ |
---|
108 | iw_u.parts.msw = (ix0); \ |
---|
109 | iw_u.parts.lsw = (ix1); \ |
---|
110 | (d) = iw_u.value; \ |
---|
111 | } while (0) |
---|
112 | |
---|
113 | /* Set the more significant 32 bits of a double from an int. */ |
---|
114 | |
---|
115 | #define SET_HIGH_WORD(d,v) \ |
---|
116 | do { \ |
---|
117 | ieee_double_shape_type sh_u; \ |
---|
118 | sh_u.value = (d); \ |
---|
119 | sh_u.parts.msw = (v); \ |
---|
120 | (d) = sh_u.value; \ |
---|
121 | } while (0) |
---|
122 | |
---|
123 | /* Set the less significant 32 bits of a double from an int. */ |
---|
124 | |
---|
125 | #define SET_LOW_WORD(d,v) \ |
---|
126 | do { \ |
---|
127 | ieee_double_shape_type sl_u; \ |
---|
128 | sl_u.value = (d); \ |
---|
129 | sl_u.parts.lsw = (v); \ |
---|
130 | (d) = sl_u.value; \ |
---|
131 | } while (0) |
---|
132 | |
---|
133 | int __ieee754_rem_pio2 (double,double*); |
---|
134 | double __ieee754_pow(double x, double y); |
---|
135 | //double __ieee754_sqrt(double x); |
---|
136 | |
---|
137 | int __kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec, const int32_t *ipio2); |
---|
138 | double __kernel_sin (double,double,int); |
---|
139 | double __kernel_cos (double,double); |
---|
140 | |
---|
141 | |
---|
142 | #endif |
---|
143 | |
---|