Annotation of hatari/src/cpu/md-fpp.h, revision 1.1.1.5

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: 
1.1.1.4   root       12: #include <math.h>
                     13: 
1.1       root       14: #define        FPCR_ROUNDING_MODE      0x00000030
                     15: #define        FPCR_ROUND_NEAR         0x00000000
                     16: #define        FPCR_ROUND_ZERO         0x00000010
                     17: #define        FPCR_ROUND_MINF         0x00000020
                     18: #define        FPCR_ROUND_PINF         0x00000030
                     19: 
                     20: #define        FPCR_ROUNDING_PRECISION 0x000000c0
                     21: #define        FPCR_PRECISION_SINGLE   0x00000040
                     22: #define        FPCR_PRECISION_DOUBLE   0x00000080
                     23: #define FPCR_PRECISION_EXTENDED        0x00000000
                     24: 
1.1.1.3   root       25: extern void to_single(fpdata *fpd, uae_u32 value);
                     26: extern void to_double(fpdata *fpd, uae_u32 wrd1, uae_u32 wrd2);
                     27: extern void to_exten(fpdata *fpd, uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3);
1.1.1.5 ! root       28: extern const TCHAR *fp_print(fpdata *fpd);
1.1.1.3   root       29: 
1.1.1.5 ! root       30: #if 0
1.1.1.3   root       31: STATIC_INLINE void exten_zeronormalize(uae_u32 *pwrd1, uae_u32 *pwrd2, uae_u32 *pwrd3)
                     32: {
                     33:        uae_u32 wrd1 = *pwrd1;
                     34:        uae_u32 wrd2 = *pwrd2;
                     35:        uae_u32 wrd3 = *pwrd3;
                     36:        int exp = (wrd1 >> 16) & 0x7fff;
                     37:        // Force zero if mantissa is zero but exponent is non-zero
                     38:        // M68k FPU automatically convert them to plain zeros.
                     39:        // x86 FPU considers them invalid values
                     40:        if (exp != 0 && exp != 0x7fff && !wrd2 && !wrd3) {
                     41:                *pwrd1 = (wrd1 & 0x80000000);
                     42:        }
                     43: }
1.1.1.2   root       44: 
1.1       root       45: #if USE_LONG_DOUBLE
1.1.1.3   root       46: STATIC_INLINE void to_exten_x(fptype *fp, uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3)
1.1       root       47: {
1.1.1.3   root       48:        // force correct long double alignment
                     49:        union
                     50:        {
                     51:                long double lf;
                     52:                uae_u32 longarray[3];
                     53:        } uld;
                     54:        exten_zeronormalize(&wrd1, &wrd2, &wrd3);
                     55:        // little endian order
                     56:        uld.longarray[0] = wrd3;
                     57:        uld.longarray[1] = wrd2;
                     58:        uld.longarray[2] = wrd1 >> 16;
                     59:        long double *longdoublewords = (long double *)uld.longarray;
                     60:        *fp = *longdoublewords;
1.1       root       61: }
                     62: #define HAVE_to_exten
                     63: 
1.1.1.3   root       64: STATIC_INLINE void from_exten_x(fptype fp, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3)
1.1       root       65: {
1.1.1.3   root       66:        uae_u32 *longarray = (uae_u32 *)&fp;
                     67:        uae_u16 *finalword = (uae_u16 *)(((uae_u8*)&fp) + 8);
1.1       root       68: 
1.1.1.3   root       69:        *wrd1 = finalword[0] << 16;
1.1.1.2   root       70:        *wrd2 = longarray[1];
                     71:        *wrd3 = longarray[0]; // little endian
1.1       root       72: }
                     73: #define HAVE_from_exten
                     74: #endif /* USE_LONG_DOUBLE */
                     75: 
1.1.1.3   root       76: #if defined(X86_MSVC_ASSEMBLY_FPU)
1.1       root       77: #ifndef HAVE_to_single
                     78: #define HAVE_to_single
1.1.1.3   root       79: STATIC_INLINE double to_single_x (uae_u32 longvalue)
1.1       root       80: {
1.1.1.3   root       81:        double floatfake;
1.1       root       82: 
1.1.1.3   root       83:        __asm {
                     84:                fld dword ptr longvalue;
                     85:                fstp qword ptr floatfake;
                     86:        }
                     87:        return floatfake;
1.1       root       88: }
                     89: #endif
                     90: 
                     91: #ifndef HAVE_from_single
                     92: #define HAVE_from_single
1.1.1.3   root       93: STATIC_INLINE uae_u32 from_single_x (double floatfake)
1.1       root       94: {
1.1.1.3   root       95:        uae_u32 longvalue;
1.1       root       96: 
1.1.1.3   root       97:        __asm {
                     98:                fld qword ptr floatfake;
                     99:                fstp dword ptr longvalue;
                    100:        }
                    101:        return longvalue;
1.1       root      102: }
                    103: #endif
                    104: 
                    105: #ifndef HAVE_to_exten
                    106: #define HAVE_to_exten
1.1.1.3   root      107: STATIC_INLINE void to_exten_x(fptype *fp, uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3)
1.1       root      108: {
1.1.1.3   root      109:        uae_u32 longarray[3];
                    110:        double  extenfake;
1.1       root      111: 
1.1.1.3   root      112:        exten_normalize(&wrd1, &wrd2, &wrd3);
                    113:        longarray[0] = wrd3; // littlen endian
                    114:        longarray[1] = wrd2;
                    115:        longarray[2] = wrd2 >> 16;
                    116: 
                    117:        __asm {
                    118:                fld tbyte ptr longarray;
                    119:                fstp qword ptr extenfake;
                    120:        }
                    121:        *fp = extenfake;
1.1       root      122: }
                    123: #endif
                    124: 
                    125: #ifndef HAVE_from_exten
                    126: #define HAVE_from_exten
1.1.1.3   root      127: STATIC_INLINE void from_exten_x(fptype fp, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3)
1.1       root      128: {
1.1.1.3   root      129:        fptype src = fp;
                    130:        uae_u32 longarray[3], *srcarray = (uae_u32 *)&src;
                    131:        __asm {
                    132:                fld qword ptr src;
                    133:                fstp tbyte ptr longarray;
                    134:        }
                    135:        *wrd1 = (longarray[2] & 0xffff) <<16;
                    136:        *wrd2 =  longarray[1];
                    137:        *wrd3 =  longarray[0]; // little endian
                    138:        if (!srcarray[0] && (srcarray[1] == 0x7ff00000 || srcarray[1] == 0xfff00000))
                    139:                *wrd2 = 0; // The MSB of the mantissa was set wrongly for infinity, causing a NaN
1.1       root      140: }
                    141: #endif
                    142: #endif /* X86_MSVC_ASSEMBLY */
                    143: 
                    144: #ifndef HAVE_to_single
                    145: #define HAVE_to_single
1.1.1.3   root      146: STATIC_INLINE double to_single_x (uae_u32 value)
1.1       root      147: {
1.1.1.3   root      148:        union {
                    149:                float f;
                    150:                uae_u32 u;
                    151:        } val;
1.1       root      152: 
1.1.1.3   root      153:        val.u = value;
                    154:        return val.f;
1.1       root      155: }
                    156: #endif
                    157: 
                    158: #ifndef HAVE_from_single
                    159: #define HAVE_from_single
1.1.1.3   root      160: STATIC_INLINE uae_u32 from_single_x (double src)
1.1       root      161: {
1.1.1.3   root      162:        union {
                    163:                float f;
                    164:                uae_u32 u;
                    165:        } val;
1.1       root      166: 
1.1.1.3   root      167:        val.f = (float) src;
                    168:        return val.u;
1.1       root      169: }
                    170: #endif
                    171: 
                    172: #ifndef HAVE_to_double
                    173: #define HAVE_to_double
1.1.1.3   root      174: STATIC_INLINE double to_double_x(uae_u32 wrd1, uae_u32 wrd2)
1.1       root      175: {
1.1.1.3   root      176:        union {
                    177:                double d;
                    178:                uae_u32 u[2];
                    179:        } val;
                    180: 
1.1.1.4   root      181: #ifdef WORDS_BIGENDIAN
                    182:        val.u[0] = wrd1;
                    183:        val.u[1] = wrd2;
                    184: #else
1.1.1.3   root      185:        val.u[1] = wrd1;
1.1.1.4   root      186:        val.u[0] = wrd2;
                    187: #endif
1.1.1.3   root      188:        return val.d;
1.1       root      189: }
                    190: #endif
                    191: 
                    192: #ifndef HAVE_from_double
                    193: #define HAVE_from_double
1.1.1.3   root      194: STATIC_INLINE void from_double_x(double src, uae_u32 * wrd1, uae_u32 * wrd2)
1.1       root      195: {
1.1.1.3   root      196:        uae_u32 *longarray = (uae_u32 *)&src;
1.1       root      197: 
1.1.1.3   root      198:        *wrd1 = longarray[1]; // little endian
                    199:        *wrd2 = longarray[0];
1.1       root      200: }
                    201: #endif
                    202: 
                    203: #ifndef HAVE_to_exten
                    204: #define HAVE_to_exten
1.1.1.3   root      205: STATIC_INLINE void to_exten_x(fptype *fp, uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3)
1.1       root      206: {
1.1.1.3   root      207:        double frac;
                    208:        exten_zeronormalize(&wrd1, &wrd2, &wrd3);
                    209:        if ((wrd1 & 0x7fff0000) == 0 && wrd2 == 0 && wrd3 == 0) {
                    210:                *fp = (wrd1 & 0x80000000) ? -0.0 : +0.0;
                    211:                return;
                    212:        }
                    213:        frac = ((double)wrd2 + ((double)wrd3 / twoto32)) / 2147483648.0;
                    214:        if (wrd1 & 0x80000000)
                    215:                frac = -frac;
                    216:        *fp = ldexp (frac, ((wrd1 >> 16) & 0x7fff) - 16383);
1.1       root      217: }
                    218: #endif
                    219: 
                    220: #ifndef HAVE_from_exten
                    221: #define HAVE_from_exten
1.1.1.3   root      222: STATIC_INLINE void from_exten_x(fptype fp, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3)
1.1       root      223: {
1.1.1.3   root      224:        int expon;
                    225:        double frac;
                    226:        fptype v;
                    227: 
                    228:        v = fp;
                    229:        if (v == 0.0) {
                    230:                *wrd1 = signbit(v) ? 0x80000000 : 0;
                    231:                *wrd2 = 0;
                    232:                *wrd3 = 0;
                    233:                return;
                    234:        }
                    235:        if (v < 0) {
                    236:                *wrd1 = 0x80000000;
                    237:                v = -v;
                    238:        } else {
                    239:                *wrd1 = 0;
                    240:        }
                    241:        frac = frexp (v, &expon);
                    242:        frac += 0.5 / (twoto32 * twoto32);
                    243:        if (frac >= 1.0) {
                    244:                frac /= 2.0;
                    245:                expon++;
                    246:        }
                    247:        *wrd1 |= (((expon + 16383 - 1) & 0x7fff) << 16);
                    248:        *wrd2 = (uae_u32) (frac * twoto32);
                    249:        *wrd3 = (uae_u32) ((frac * twoto32 - *wrd2) * twoto32);
1.1       root      250: }
                    251: #endif
1.1.1.5 ! root      252: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.