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

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: 
1.1.1.2 ! root       23: extern uae_u32 get_fpsr (void);
        !            24: 
1.1       root       25: #if USE_LONG_DOUBLE
                     26: STATIC_INLINE long double to_exten(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3)
                     27: {
                     28:     uae_u32 longarray[] = {wrd3,wrd2,((wrd1>>16)&0xffff)}; // little endian
                     29:     register long double *longdoublewords = (long double *)longarray;
                     30: 
                     31:     return(*longdoublewords);
                     32: }
                     33: #define HAVE_to_exten
                     34: 
                     35: STATIC_INLINE void from_exten(long double src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3)
                     36: {
                     37:     register uae_u32 *longarray = (uae_u32 *)&src;
                     38: 
1.1.1.2 ! root       39:        *wrd1 = (longarray[2] & 0xffff)<<16;
        !            40:        *wrd2 = longarray[1];
        !            41:        *wrd3 = longarray[0]; // little endian
1.1       root       42: }
                     43: #define HAVE_from_exten
                     44: #endif /* USE_LONG_DOUBLE */
                     45: 
                     46: #if defined(X86_MSVC_ASSEMBLY)
                     47: #ifndef HAVE_to_single
                     48: #define HAVE_to_single
                     49: STATIC_INLINE double to_single (uae_u32 longvalue)
                     50: {
                     51:     double floatfake;
                     52: 
                     53:     __asm {
                     54:     fld     dword ptr   longvalue;
                     55:     fstp    qword ptr   floatfake;
                     56:     }
                     57:     return(floatfake);
                     58: }
                     59: #endif
                     60: 
                     61: #ifndef HAVE_from_single
                     62: #define HAVE_from_single
                     63: STATIC_INLINE uae_u32 from_single (double floatfake)
                     64: {
                     65:     uae_u32 longvalue;
                     66: 
                     67:     __asm {
                     68:     fld     qword ptr   floatfake;
                     69:     fstp    dword ptr   longvalue;
                     70:     }
                     71:     return(longvalue);
                     72: }
                     73: #endif
                     74: 
                     75: #ifndef HAVE_to_exten
                     76: #define HAVE_to_exten
                     77: STATIC_INLINE double to_exten(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3)
                     78: {
                     79:     uae_u32 longarray[] = {wrd3,wrd2,((wrd1>>16)&0xffff)}; // little endian
                     80:     double  extenfake;
                     81: 
                     82:     __asm {
                     83:     fld     tbyte ptr   longarray;
                     84:     fstp    qword ptr   extenfake;
                     85:     }
                     86:     return(extenfake);
                     87: }
                     88: #endif
                     89: 
                     90: #ifndef HAVE_from_exten
                     91: #define HAVE_from_exten
                     92: STATIC_INLINE void from_exten(double src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3)
                     93: {
                     94:     uae_u32 longarray[3], *srcarray = (uae_u32 *)&src;
                     95: 
                     96:     __asm {
                     97:     fld     qword ptr   src;
                     98:     fstp    tbyte ptr   longarray;
                     99:     }
                    100:     *wrd1 = (longarray[2] & 0xffff) <<16;
                    101:     *wrd2 =  longarray[1];
                    102:     *wrd3 =  longarray[0]; // little endian
                    103:     if (!srcarray[0] && (srcarray[1]==0x7ff00000 || srcarray[1]==0xfff00000))
                    104:        *wrd2 = 0; // The MSB of the mantissa was set wrongly for infinity, causing a NaN
                    105: }
                    106: #endif
                    107: #endif /* X86_MSVC_ASSEMBLY */
                    108: 
                    109: #ifndef HAVE_to_single
                    110: #define HAVE_to_single
                    111: STATIC_INLINE double to_single (uae_u32 value)
                    112: {
                    113:     union {
                    114:     float f;
                    115:     uae_u32 u;
                    116:     } val;
                    117: 
                    118:     val.u = value;
                    119:     return val.f;
                    120: }
                    121: #endif
                    122: 
                    123: #ifndef HAVE_from_single
                    124: #define HAVE_from_single
                    125: STATIC_INLINE uae_u32 from_single (double src)
                    126: {
                    127:     union {
                    128:     float f;
                    129:     uae_u32 u;
                    130:     } val;
                    131: 
                    132:     val.f = (float) src;
                    133:     return val.u;
                    134: }
                    135: #endif
                    136: 
                    137: #ifndef HAVE_to_double
                    138: #define HAVE_to_double
                    139: STATIC_INLINE double to_double(uae_u32 wrd1, uae_u32 wrd2)
                    140: {
                    141:     union {
                    142:     double d;
                    143:     uae_u32 u[2];
                    144:     } val;
                    145: 
                    146:     val.u[0] = wrd2; // little endian
                    147:     val.u[1] = wrd1;
                    148:     return val.d;
                    149: }
                    150: #endif
                    151: 
                    152: #ifndef HAVE_from_double
                    153: #define HAVE_from_double
                    154: STATIC_INLINE void from_double(double src, uae_u32 * wrd1, uae_u32 * wrd2)
                    155: {
1.1.1.2 ! root      156:     union {
        !           157:     double d;
        !           158:     uae_u32 u[2];
        !           159:     } val;
1.1       root      160: 
1.1.1.2 ! root      161:     val.d = src;
        !           162:     *wrd1 = val.u[1]; // little endian
        !           163:     *wrd2 = val.u[0];
1.1       root      164: }
                    165: #endif
                    166: 
                    167: static double twoto32 = 4294967296.0;
                    168: #ifndef HAVE_to_exten
                    169: #define HAVE_to_exten
                    170: STATIC_INLINE double to_exten(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3)
                    171: {
                    172:     double frac;
                    173: 
                    174:     if ((wrd1 & 0x7fff0000) == 0 && wrd2 == 0 && wrd3 == 0)
                    175:        return 0.0;
                    176:     frac = ((double)wrd2 + ((double)wrd3 / twoto32)) / 2147483648.0;
                    177:     if (wrd1 & 0x80000000)
                    178:        frac = -frac;
                    179:     return ldexp (frac, ((wrd1 >> 16) & 0x7fff) - 16383);
                    180: }
                    181: #endif
                    182: 
                    183: #ifndef HAVE_from_exten
                    184: #define HAVE_from_exten
                    185: STATIC_INLINE void from_exten(double src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3)
                    186: {
                    187:     int expon;
                    188:     double frac;
                    189: 
                    190:     if (src == 0.0) {
                    191:        *wrd1 = 0;
                    192:        *wrd2 = 0;
                    193:        *wrd3 = 0;
                    194:        return;
                    195:     }
                    196:     if (src < 0) {
                    197:        *wrd1 = 0x80000000;
                    198:        src = -src;
                    199:     } else {
                    200:        *wrd1 = 0;
                    201:     }
                    202:     frac = frexp (src, &expon);
                    203:     frac += 0.5 / (twoto32 * twoto32);
                    204:     if (frac >= 1.0) {
                    205:        frac /= 2.0;
                    206:        expon++;
                    207:     }
                    208:     *wrd1 |= (((expon + 16383 - 1) & 0x7fff) << 16);
                    209:     *wrd2 = (uae_u32) (frac * twoto32);
                    210:     *wrd3 = (uae_u32) ((frac * twoto32 - *wrd2) * twoto32);
                    211: }
                    212: #endif

unix.superglobalmegacorp.com

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