|
|
1.1 ! root 1: /* ! 2: * UAE - The Un*x Amiga Emulator ! 3: * ! 4: * MC68881 emulation ! 5: * ! 6: * Conversion routines for hosts knowing floating point format. ! 7: * ! 8: * Copyright 1996 Herman ten Brugge ! 9: * Modified 2005 Peter Keunecke ! 10: */ ! 11: ! 12: #define FPCR_ROUNDING_MODE 0x00000030 ! 13: #define FPCR_ROUND_NEAR 0x00000000 ! 14: #define FPCR_ROUND_ZERO 0x00000010 ! 15: #define FPCR_ROUND_MINF 0x00000020 ! 16: #define FPCR_ROUND_PINF 0x00000030 ! 17: ! 18: #define FPCR_ROUNDING_PRECISION 0x000000c0 ! 19: #define FPCR_PRECISION_SINGLE 0x00000040 ! 20: #define FPCR_PRECISION_DOUBLE 0x00000080 ! 21: #define FPCR_PRECISION_EXTENDED 0x00000000 ! 22: ! 23: #if USE_LONG_DOUBLE ! 24: STATIC_INLINE long double to_exten(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3) ! 25: { ! 26: uae_u32 longarray[] = {wrd3,wrd2,((wrd1>>16)&0xffff)}; // little endian ! 27: register long double *longdoublewords = (long double *)longarray; ! 28: ! 29: return(*longdoublewords); ! 30: } ! 31: #define HAVE_to_exten ! 32: ! 33: STATIC_INLINE void from_exten(long double src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3) ! 34: { ! 35: register uae_u32 *longarray = (uae_u32 *)&src; ! 36: register uae_u16 *finalword = (uae_u16 *)(&src + 8); ! 37: ! 38: *wrd1 = ((uae_u32)*finalword)<<16; ! 39: *wrd2 = longarray[1]; ! 40: *wrd3 = longarray[0]; // little endian ! 41: } ! 42: #define HAVE_from_exten ! 43: #endif /* USE_LONG_DOUBLE */ ! 44: ! 45: #if defined(X86_MSVC_ASSEMBLY) ! 46: #ifndef HAVE_to_single ! 47: #define HAVE_to_single ! 48: STATIC_INLINE double to_single (uae_u32 longvalue) ! 49: { ! 50: double floatfake; ! 51: ! 52: __asm { ! 53: fld dword ptr longvalue; ! 54: fstp qword ptr floatfake; ! 55: } ! 56: return(floatfake); ! 57: } ! 58: #endif ! 59: ! 60: #ifndef HAVE_from_single ! 61: #define HAVE_from_single ! 62: STATIC_INLINE uae_u32 from_single (double floatfake) ! 63: { ! 64: uae_u32 longvalue; ! 65: ! 66: __asm { ! 67: fld qword ptr floatfake; ! 68: fstp dword ptr longvalue; ! 69: } ! 70: return(longvalue); ! 71: } ! 72: #endif ! 73: ! 74: #ifndef HAVE_to_exten ! 75: #define HAVE_to_exten ! 76: STATIC_INLINE double to_exten(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3) ! 77: { ! 78: uae_u32 longarray[] = {wrd3,wrd2,((wrd1>>16)&0xffff)}; // little endian ! 79: double extenfake; ! 80: ! 81: __asm { ! 82: fld tbyte ptr longarray; ! 83: fstp qword ptr extenfake; ! 84: } ! 85: return(extenfake); ! 86: } ! 87: #endif ! 88: ! 89: #ifndef HAVE_from_exten ! 90: #define HAVE_from_exten ! 91: STATIC_INLINE void from_exten(double src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3) ! 92: { ! 93: uae_u32 longarray[3], *srcarray = (uae_u32 *)&src; ! 94: ! 95: __asm { ! 96: fld qword ptr src; ! 97: fstp tbyte ptr longarray; ! 98: } ! 99: *wrd1 = (longarray[2] & 0xffff) <<16; ! 100: *wrd2 = longarray[1]; ! 101: *wrd3 = longarray[0]; // little endian ! 102: if (!srcarray[0] && (srcarray[1]==0x7ff00000 || srcarray[1]==0xfff00000)) ! 103: *wrd2 = 0; // The MSB of the mantissa was set wrongly for infinity, causing a NaN ! 104: } ! 105: #endif ! 106: #endif /* X86_MSVC_ASSEMBLY */ ! 107: ! 108: #ifndef HAVE_to_single ! 109: #define HAVE_to_single ! 110: STATIC_INLINE double to_single (uae_u32 value) ! 111: { ! 112: union { ! 113: float f; ! 114: uae_u32 u; ! 115: } val; ! 116: ! 117: val.u = value; ! 118: return val.f; ! 119: } ! 120: #endif ! 121: ! 122: #ifndef HAVE_from_single ! 123: #define HAVE_from_single ! 124: STATIC_INLINE uae_u32 from_single (double src) ! 125: { ! 126: union { ! 127: float f; ! 128: uae_u32 u; ! 129: } val; ! 130: ! 131: val.f = (float) src; ! 132: return val.u; ! 133: } ! 134: #endif ! 135: ! 136: #ifndef HAVE_to_double ! 137: #define HAVE_to_double ! 138: STATIC_INLINE double to_double(uae_u32 wrd1, uae_u32 wrd2) ! 139: { ! 140: union { ! 141: double d; ! 142: uae_u32 u[2]; ! 143: } val; ! 144: ! 145: val.u[0] = wrd2; // little endian ! 146: val.u[1] = wrd1; ! 147: return val.d; ! 148: } ! 149: #endif ! 150: ! 151: #ifndef HAVE_from_double ! 152: #define HAVE_from_double ! 153: STATIC_INLINE void from_double(double src, uae_u32 * wrd1, uae_u32 * wrd2) ! 154: { ! 155: register uae_u32 *longarray = (uae_u32 *)&src; ! 156: ! 157: *wrd1 = longarray[1]; // little endian ! 158: *wrd2 = longarray[0]; ! 159: } ! 160: #endif ! 161: ! 162: static double twoto32 = 4294967296.0; ! 163: #ifndef HAVE_to_exten ! 164: #define HAVE_to_exten ! 165: STATIC_INLINE double to_exten(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3) ! 166: { ! 167: double frac; ! 168: ! 169: if ((wrd1 & 0x7fff0000) == 0 && wrd2 == 0 && wrd3 == 0) ! 170: return 0.0; ! 171: frac = ((double)wrd2 + ((double)wrd3 / twoto32)) / 2147483648.0; ! 172: if (wrd1 & 0x80000000) ! 173: frac = -frac; ! 174: return ldexp (frac, ((wrd1 >> 16) & 0x7fff) - 16383); ! 175: } ! 176: #endif ! 177: ! 178: #ifndef HAVE_from_exten ! 179: #define HAVE_from_exten ! 180: STATIC_INLINE void from_exten(double src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3) ! 181: { ! 182: int expon; ! 183: double frac; ! 184: ! 185: if (src == 0.0) { ! 186: *wrd1 = 0; ! 187: *wrd2 = 0; ! 188: *wrd3 = 0; ! 189: return; ! 190: } ! 191: if (src < 0) { ! 192: *wrd1 = 0x80000000; ! 193: src = -src; ! 194: } else { ! 195: *wrd1 = 0; ! 196: } ! 197: frac = frexp (src, &expon); ! 198: frac += 0.5 / (twoto32 * twoto32); ! 199: if (frac >= 1.0) { ! 200: frac /= 2.0; ! 201: expon++; ! 202: } ! 203: *wrd1 |= (((expon + 16383 - 1) & 0x7fff) << 16); ! 204: *wrd2 = (uae_u32) (frac * twoto32); ! 205: *wrd3 = (uae_u32) ((frac * twoto32 - *wrd2) * twoto32); ! 206: } ! 207: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.