|
|
1.1 root 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:
1.1.1.2 root 11: #include <SDL_endian.h>
12:
13: typedef double fpu_register;
1.1.1.3 ! root 14:
1.1.1.2 root 15: typedef union {
16: fpu_register val;
17: uae_u32 parts[sizeof(fpu_register) / 4];
18: } fpu_register_parts;
1.1.1.3 ! root 19:
1.1.1.2 root 20: enum {
21: #if SDL_BYTEORDER == SDL_BIG_ENDIAN
22: FHI = 0,
23: FLO = 1
24: #else
25: FHI = 1,
26: FLO = 0
27: #endif
28: };
29:
30:
1.1 root 31: #ifndef HAVE_to_single
1.1.1.2 root 32: STATIC_INLINE double to_single(uae_u32 value)
1.1 root 33: {
1.1.1.2 root 34: uae_u32 sign;
35: uae_u32 expon;
1.1.1.3 ! root 36: fpu_register_parts result;
1.1 root 37:
1.1.1.2 root 38: if ((value & 0x7fffffff) == 0)
39: return (0.0);
40:
41: sign = (value & 0x80000000);
42: expon = ((value & 0x7F800000) >> 23) + 1023 - 127;
43:
1.1.1.3 ! root 44: result.parts[FLO] = value << 29;
! 45: result.parts[FHI] = sign | (expon << 20) | ((value & 0x007FFFFF) >> 3);
1.1.1.2 root 46:
1.1.1.3 ! root 47: return result.val;
1.1 root 48: }
49: #endif
50:
51: #ifndef HAVE_from_single
1.1.1.2 root 52: STATIC_INLINE uae_u32 from_single(double src)
1.1 root 53: {
1.1.1.2 root 54: uae_u32 sign;
55: uae_u32 expon;
56: uae_u32 result;
57: fpu_register_parts const *p = (fpu_register_parts const *)&src;
58:
59: if (src == 0.0)
60: return 0;
61:
62: sign = (p->parts[FHI] & 0x80000000);
63: expon = (p->parts[FHI] & 0x7FF00000) >> 20;
64:
65: if (expon + 127 < 1023) {
66: expon = 0;
67: } else if (expon > 1023 + 127) {
68: expon = 255;
69: } else {
70: expon = expon + 127 - 1023;
71: }
1.1 root 72:
1.1.1.2 root 73: result = sign | (expon << 23) | ((p->parts[FHI] & 0x000FFFFF) << 3) | (p->parts[FLO] >> 29);
74:
75: return result;
1.1 root 76: }
77: #endif
78:
79: #ifndef HAVE_to_exten
80: STATIC_INLINE double to_exten(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3)
81: {
82: double frac;
83:
84: if ((wrd1 & 0x7fff0000) == 0 && wrd2 == 0 && wrd3 == 0)
85: return 0.0;
86: frac = (double) wrd2 / 2147483648.0 +
87: (double) wrd3 / 9223372036854775808.0;
88: if (wrd1 & 0x80000000)
89: frac = -frac;
90: return ldexp (frac, ((wrd1 >> 16) & 0x7fff) - 16383);
91: }
92: #endif
93:
94: #ifndef HAVE_from_exten
95: STATIC_INLINE void from_exten(double src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3)
96: {
97: int expon;
98: double frac;
99:
100: if (src == 0.0) {
101: *wrd1 = 0;
102: *wrd2 = 0;
103: *wrd3 = 0;
104: return;
105: }
106: if (src < 0) {
107: *wrd1 = 0x80000000;
108: src = -src;
109: } else {
110: *wrd1 = 0;
111: }
112: frac = frexp (src, &expon);
113: frac += 0.5 / 18446744073709551616.0;
114: if (frac >= 1.0) {
115: frac /= 2.0;
116: expon++;
117: }
118: *wrd1 |= (((expon + 16383 - 1) & 0x7fff) << 16);
119: *wrd2 = (uae_u32) (frac * 4294967296.0);
120: *wrd3 = (uae_u32) (frac * 18446744073709551616.0 - *wrd2 * 4294967296.0);
121: }
122: #endif
123:
124: #ifndef HAVE_to_double
125: STATIC_INLINE double to_double(uae_u32 wrd1, uae_u32 wrd2)
126: {
1.1.1.3 ! root 127: fpu_register_parts result;
1.1 root 128:
1.1.1.2 root 129: if ((wrd1 & 0x7fffffff) == 0 && wrd2 == 0)
130: return 0.0;
131:
1.1.1.3 ! root 132: result.parts[FLO] = wrd2;
! 133: result.parts[FHI] = wrd1;
1.1.1.2 root 134:
1.1.1.3 ! root 135: return result.val;
1.1 root 136: }
137: #endif
138:
139: #ifndef HAVE_from_double
140: STATIC_INLINE void from_double(double src, uae_u32 * wrd1, uae_u32 * wrd2)
141: {
1.1.1.2 root 142: /*
143: if (src == 0.0) {
144: *wrd1 = *wrd2 = 0;
145: return;
146: }
147: */
148: fpu_register_parts const *p = (fpu_register_parts const *)&src;
149: *wrd2 = p->parts[FLO];
150: *wrd1 = p->parts[FHI];
1.1 root 151: }
152: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.