Annotation of hatari/src/uae-cpu/fpp-unknown.h, revision 1.1.1.3

1.1       root        1:  /*
                      2:   * UAE - The Un*x Amiga Emulator
                      3:   *
                      4:   * MC68881 emulation
                      5:   *
                      6:   * Conversion routines for hosts with unknown floating point format.
                      7:   *
                      8:   * Copyright 1996 Herman ten Brugge
                      9:   */
                     10: 
1.1.1.2   root       11: #include <SDL_endian.h>
                     12: 
                     13: typedef double fpu_register;
1.1.1.3 ! root       14: 
1.1.1.2   root       15: typedef union {
                     16:        fpu_register val;
                     17:        uae_u32 parts[sizeof(fpu_register) / 4];
                     18: } fpu_register_parts;
1.1.1.3 ! root       19: 
1.1.1.2   root       20: enum {
                     21: #if SDL_BYTEORDER == SDL_BIG_ENDIAN
                     22:        FHI             = 0,
                     23:        FLO             = 1
                     24: #else
                     25:        FHI             = 1,
                     26:        FLO             = 0
                     27: #endif
                     28: };
                     29: 
                     30: 
1.1       root       31: #ifndef HAVE_to_single
1.1.1.2   root       32: STATIC_INLINE double to_single(uae_u32 value)
1.1       root       33: {
1.1.1.2   root       34:        uae_u32 sign;
                     35:        uae_u32 expon;
1.1.1.3 ! root       36:        fpu_register_parts result;
1.1       root       37: 
1.1.1.2   root       38:        if ((value & 0x7fffffff) == 0)
                     39:                return (0.0);
                     40: 
                     41:        sign = (value & 0x80000000);
                     42:        expon  = ((value & 0x7F800000) >> 23) + 1023 - 127;
                     43: 
1.1.1.3 ! root       44:        result.parts[FLO] = value << 29;
        !            45:        result.parts[FHI] = sign | (expon << 20) | ((value & 0x007FFFFF) >> 3);
1.1.1.2   root       46: 
1.1.1.3 ! root       47:        return result.val;
1.1       root       48: }
                     49: #endif
                     50: 
                     51: #ifndef HAVE_from_single
1.1.1.2   root       52: STATIC_INLINE uae_u32 from_single(double src)
1.1       root       53: {
1.1.1.2   root       54:        uae_u32 sign;
                     55:        uae_u32 expon;
                     56:        uae_u32 result;
                     57:        fpu_register_parts const *p = (fpu_register_parts const *)&src;
                     58: 
                     59:        if (src == 0.0)
                     60:                return 0;
                     61: 
                     62:        sign  = (p->parts[FHI] & 0x80000000);
                     63:        expon = (p->parts[FHI] & 0x7FF00000) >> 20;
                     64: 
                     65:        if (expon + 127 < 1023) {
                     66:                expon = 0;
                     67:        } else if (expon > 1023 + 127) {
                     68:                expon = 255;
                     69:        } else {
                     70:                expon = expon + 127 - 1023;
                     71:        }
1.1       root       72: 
1.1.1.2   root       73:        result = sign | (expon << 23) | ((p->parts[FHI] & 0x000FFFFF) << 3) | (p->parts[FLO] >> 29);
                     74: 
                     75:        return result;
1.1       root       76: }
                     77: #endif
                     78: 
                     79: #ifndef HAVE_to_exten
                     80: STATIC_INLINE double to_exten(uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3)
                     81: {
                     82:     double frac;
                     83: 
                     84:     if ((wrd1 & 0x7fff0000) == 0 && wrd2 == 0 && wrd3 == 0)
                     85:         return 0.0;
                     86:     frac = (double) wrd2 / 2147483648.0 +
                     87:         (double) wrd3 / 9223372036854775808.0;
                     88:     if (wrd1 & 0x80000000)
                     89:         frac = -frac;
                     90:     return ldexp (frac, ((wrd1 >> 16) & 0x7fff) - 16383);
                     91: }
                     92: #endif
                     93: 
                     94: #ifndef HAVE_from_exten
                     95: STATIC_INLINE void from_exten(double src, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3)
                     96: {
                     97:     int expon;
                     98:     double frac;
                     99: 
                    100:     if (src == 0.0) {
                    101:         *wrd1 = 0;
                    102:         *wrd2 = 0;
                    103:         *wrd3 = 0;
                    104:         return;
                    105:     }
                    106:     if (src < 0) {
                    107:         *wrd1 = 0x80000000;
                    108:         src = -src;
                    109:     } else {
                    110:         *wrd1 = 0;
                    111:     }
                    112:     frac = frexp (src, &expon);
                    113:     frac += 0.5 / 18446744073709551616.0;
                    114:     if (frac >= 1.0) {
                    115:         frac /= 2.0;
                    116:         expon++;
                    117:     }
                    118:     *wrd1 |= (((expon + 16383 - 1) & 0x7fff) << 16);
                    119:     *wrd2 = (uae_u32) (frac * 4294967296.0);
                    120:     *wrd3 = (uae_u32) (frac * 18446744073709551616.0 - *wrd2 * 4294967296.0);
                    121: }
                    122: #endif
                    123: 
                    124: #ifndef HAVE_to_double
                    125: STATIC_INLINE double to_double(uae_u32 wrd1, uae_u32 wrd2)
                    126: {
1.1.1.3 ! root      127:        fpu_register_parts result;
1.1       root      128: 
1.1.1.2   root      129:        if ((wrd1 & 0x7fffffff) == 0 && wrd2 == 0)
                    130:                return 0.0;
                    131: 
1.1.1.3 ! root      132:        result.parts[FLO] = wrd2;
        !           133:        result.parts[FHI] = wrd1;
1.1.1.2   root      134: 
1.1.1.3 ! root      135:        return result.val;
1.1       root      136: }
                    137: #endif
                    138: 
                    139: #ifndef HAVE_from_double
                    140: STATIC_INLINE void from_double(double src, uae_u32 * wrd1, uae_u32 * wrd2)
                    141: {
1.1.1.2   root      142: /*
                    143:        if (src == 0.0) {
                    144:                *wrd1 = *wrd2 = 0;
                    145:                return;
                    146:        }
                    147: */
                    148:        fpu_register_parts const *p = (fpu_register_parts const *)&src;
                    149:        *wrd2 = p->parts[FLO];
                    150:        *wrd1 = p->parts[FHI];
1.1       root      151: }
                    152: #endif

unix.superglobalmegacorp.com

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