Annotation of hatari/src/cpu/md-fpp.h, revision 1.1.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.