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

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

unix.superglobalmegacorp.com

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