|
|
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: ! 11: #include <SDL_endian.h> ! 12: ! 13: typedef double fpu_register; ! 14: ! 15: typedef union { ! 16: fpu_register val; ! 17: uae_u32 parts[sizeof(fpu_register) / 4]; ! 18: } fpu_register_parts; ! 19: ! 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: ! 31: #ifndef HAVE_to_single ! 32: STATIC_INLINE double to_single(uae_u32 value) ! 33: { ! 34: uae_u32 sign; ! 35: uae_u32 expon; ! 36: fpu_register_parts result; ! 37: ! 38: if ((value & 0x7fffffff) == 0) ! 39: return (0.0); ! 40: ! 41: sign = (value & 0x80000000); ! 42: expon = ((value & 0x7F800000) >> 23) + 1023 - 127; ! 43: ! 44: result.parts[FLO] = value << 29; ! 45: result.parts[FHI] = sign | (expon << 20) | ((value & 0x007FFFFF) >> 3); ! 46: ! 47: return result.val; ! 48: } ! 49: #endif ! 50: ! 51: #ifndef HAVE_from_single ! 52: STATIC_INLINE uae_u32 from_single(double src) ! 53: { ! 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: } ! 72: ! 73: result = sign | (expon << 23) | ((p->parts[FHI] & 0x000FFFFF) << 3) | (p->parts[FLO] >> 29); ! 74: ! 75: return result; ! 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: { ! 127: fpu_register_parts result; ! 128: ! 129: if ((wrd1 & 0x7fffffff) == 0 && wrd2 == 0) ! 130: return 0.0; ! 131: ! 132: result.parts[FLO] = wrd2; ! 133: result.parts[FHI] = wrd1; ! 134: ! 135: return result.val; ! 136: } ! 137: #endif ! 138: ! 139: #ifndef HAVE_from_double ! 140: STATIC_INLINE void from_double(double src, uae_u32 * wrd1, uae_u32 * wrd2) ! 141: { ! 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]; ! 151: } ! 152: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.