1  /*
2   * UAE - The Un*x Amiga Emulator
3   *
4   * MC68881 emulation
5   *
6   * Conversion routines for hosts with unknown floating point format.
7   *
8   * Copyright 1996 Herman ten Brugge
9   */
10 
11 #ifndef UAE_FPP_UNKNOWN_H
12 #define UAE_FPP_UNKNOWN_H
13 
14 #include "uae/types.h"
15 #ifdef FSUAE
16 #include "uae/inline.h"
17 #include <math.h>
18 #endif
19 
20 #ifndef HAVE_to_single
to_single(uae_u32 value)21 STATIC_INLINE double to_single (uae_u32 value)
22 {
23     double frac;
24 
25     if ((value & 0x7fffffff) == 0)
26 	return (0.0);
27     frac = (double) ((value & 0x7fffff) | 0x800000) / 8388608.0;
28     if (value & 0x80000000)
29 	frac = -frac;
30     return (ldexp (frac, ((value >> 23) & 0xff) - 127));
31 }
32 #endif
33 
34 #ifndef HAVE_from_single
from_single(double src)35 STATIC_INLINE uae_u32 from_single (double src)
36 {
37     int expon;
38     uae_u32 tmp;
39     double frac;
40 
41     if (src == 0.0)
42 	return 0;
43     if (src < 0) {
44 	tmp = 0x80000000;
45 	src = -src;
46     } else {
47 	tmp = 0;
48     }
49     frac = frexp (src, &expon);
50     frac += 0.5 / 16777216.0;
51     if (frac >= 1.0) {
52 	frac /= 2.0;
53 	expon++;
54     }
55     return (tmp | (((expon + 127 - 1) & 0xff) << 23) |
56 	    (((int) (frac * 16777216.0)) & 0x7fffff));
57 }
58 #endif
59 
60 #ifndef HAVE_to_exten
to_exten(uae_u32 wrd1,uae_u32 wrd2,uae_u32 wrd3)61 STATIC_INLINE double to_exten(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3)
62 {
63     double frac;
64 
65     if ((wrd1 & 0x7fff0000) == 0 && wrd2 == 0 && wrd3 == 0)
66 	return 0.0;
67     frac = (double) wrd2 / 2147483648.0 +
68 	(double) wrd3 / 9223372036854775808.0;
69     if (wrd1 & 0x80000000)
70 	frac = -frac;
71     return ldexp (frac, ((wrd1 >> 16) & 0x7fff) - 16383);
72 }
73 #endif
74 
75 #ifndef HAVE_from_exten
from_exten(double src,uae_u32 * wrd1,uae_u32 * wrd2,uae_u32 * wrd3)76 STATIC_INLINE void from_exten(double src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3)
77 {
78     int expon;
79     double frac;
80 
81     if (src == 0.0) {
82 	*wrd1 = 0;
83 	*wrd2 = 0;
84 	*wrd3 = 0;
85 	return;
86     }
87     if (src < 0) {
88 	*wrd1 = 0x80000000;
89 	src = -src;
90     } else {
91 	*wrd1 = 0;
92     }
93     frac = frexp (src, &expon);
94     frac += 0.5 / 18446744073709551616.0;
95     if (frac >= 1.0) {
96 	frac /= 2.0;
97 	expon++;
98     }
99     *wrd1 |= (((expon + 16383 - 1) & 0x7fff) << 16);
100     *wrd2 = (uae_u32) (frac * 4294967296.0);
101     *wrd3 = (uae_u32) (frac * 18446744073709551616.0 - *wrd2 * 4294967296.0);
102 }
103 #endif
104 
105 #ifndef HAVE_to_double
to_double(uae_u32 wrd1,uae_u32 wrd2)106 STATIC_INLINE double to_double(uae_u32 wrd1, uae_u32 wrd2)
107 {
108     double frac;
109 
110     if ((wrd1 & 0x7fffffff) == 0 && wrd2 == 0)
111 	return 0.0;
112     frac = (double) ((wrd1 & 0xfffff) | 0x100000) / 1048576.0 +
113 	(double) wrd2 / 4503599627370496.0;
114     if (wrd1 & 0x80000000)
115 	frac = -frac;
116     return ldexp (frac, ((wrd1 >> 20) & 0x7ff) - 1023);
117 }
118 #endif
119 
120 #ifndef HAVE_from_double
from_double(double src,uae_u32 * wrd1,uae_u32 * wrd2)121 STATIC_INLINE void from_double(double src, uae_u32 * wrd1, uae_u32 * wrd2)
122 {
123     int expon;
124     int tmp;
125     double frac;
126 
127     if (src == 0.0) {
128 	*wrd1 = 0;
129 	*wrd2 = 0;
130 	return;
131     }
132     if (src < 0) {
133 	*wrd1 = 0x80000000;
134 	src = -src;
135     } else {
136 	*wrd1 = 0;
137     }
138     frac = frexp (src, &expon);
139     frac += 0.5 / 9007199254740992.0;
140     if (frac >= 1.0) {
141 	frac /= 2.0;
142 	expon++;
143     }
144     tmp = (uae_u32) (frac * 2097152.0);
145     *wrd1 |= (((expon + 1023 - 1) & 0x7ff) << 20) | (tmp & 0xfffff);
146     *wrd2 = (uae_u32) (frac * 9007199254740992.0 - tmp * 4294967296.0);
147 }
148 #endif
149 
150 #endif /* UAE_FPP_UNKNOWN_H */
151