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

unix.superglobalmegacorp.com

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