]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
FPU update 18c merge.
authorToni Wilen <twilen@winuae.net>
Fri, 3 Feb 2017 21:33:57 +0000 (23:33 +0200)
committerToni Wilen <twilen@winuae.net>
Fri, 3 Feb 2017 21:33:57 +0000 (23:33 +0200)
fpp.cpp
fpp_native.cpp
fpp_softfloat.cpp
include/fpp.h
softfloat/softfloat.cpp
softfloat/softfloat.h

diff --git a/fpp.cpp b/fpp.cpp
index af152c1e4189348cb9fca760df1cf792343fbdba..c0a2fe36cc1af9ed152912bdded348feb3b7381c 100644 (file)
--- a/fpp.cpp
+++ b/fpp.cpp
@@ -54,16 +54,14 @@ FPP_TO_NATIVE fpp_to_native;
 FPP_TO_INT fpp_to_int;
 FPP_FROM_INT fpp_from_int;
 
-FPP_TO_SINGLE fpp_to_single_xn;
-FPP_TO_SINGLE fpp_to_single_x;
-FPP_FROM_SINGLE fpp_from_single_x;
-
-FPP_TO_DOUBLE fpp_to_double_xn;
-FPP_TO_DOUBLE fpp_to_double_x;
-FPP_FROM_DOUBLE fpp_from_double_x;
-
-FPP_TO_EXTEN fpp_to_exten_x;
-FPP_FROM_EXTEN fpp_from_exten_x;
+FPP_TO_SINGLE fpp_to_single;
+FPP_FROM_SINGLE fpp_from_single;
+FPP_TO_DOUBLE fpp_to_double;
+FPP_FROM_DOUBLE fpp_from_double;
+FPP_TO_EXTEN fpp_to_exten;
+FPP_FROM_EXTEN fpp_from_exten;
+FPP_TO_EXTEN fpp_to_exten_fmovem;
+FPP_FROM_EXTEN fpp_from_exten_fmovem;
 
 FPP_A fpp_normalize;
 
@@ -106,6 +104,8 @@ FPP_AB fpp_sub;
 FPP_AB fpp_sgldiv;
 FPP_AB fpp_sglmul;
 FPP_AB fpp_cmp;
+FPP_AB fpp_tst;
+FPP_AB fpp_move;
 
 #define DEBUG_FPP 0
 #define EXCEPTION_FPP 1
@@ -198,54 +198,6 @@ static void normalize_exten(uae_u32 *pwrd1, uae_u32 *pwrd2, uae_u32 *pwrd3)
     }
 }
 
-void to_single(fpdata *fpd, uae_u32 wrd1)
-{
-#if 0 // now done in get_fp_value
-       // automatically fix denormals if 6888x
-    if (currprefs.fpu_model == 68881 || currprefs.fpu_model == 68882)
-        fpp_to_single_xn(fpd, wrd1);
-    else
-#endif
-               fpp_to_single_x(fpd, wrd1);
-}
-static uae_u32 from_single(fpdata *fpd)
-{
-    return fpp_from_single_x(fpd);
-}
-void to_double(fpdata *fpd, uae_u32 wrd1, uae_u32 wrd2)
-{
-#if 0 // now done in get_fp_value
-    // automatically fix denormals if 6888x
-    if (currprefs.fpu_model == 68881 || currprefs.fpu_model == 68882)
-        fpp_to_double_xn(fpd, wrd1, wrd2);
-    else
-#endif
-               fpp_to_double_x(fpd, wrd1, wrd2);
-}
-static void from_double(fpdata *fpd, uae_u32 *wrd1, uae_u32 *wrd2)
-{
-    fpp_from_double_x(fpd, wrd1, wrd2);
-}
-
-void to_exten(fpdata *fpd, uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3)
-{
-#if 0 // now done in get_fp_value
-    // automatically fix unnormals if 6888x
-       if (currprefs.fpu_model == 68881 || currprefs.fpu_model == 68882) {
-               normalize_exten(&wrd1, &wrd2, &wrd3);
-       }
-#endif
-       fpp_to_exten_x(fpd, wrd1, wrd2, wrd3);
-}
-static void to_exten_fmovem(fpdata *fpd, uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3)
-{
-       fpp_to_exten_x(fpd, wrd1, wrd2, wrd3);
-}
-static void from_exten(fpdata *fpd, uae_u32 * wrd1, uae_u32 * wrd2, uae_u32 * wrd3)
-{
-       fpp_from_exten_x(fpd, wrd1, wrd2, wrd3);
-}
-
 /* Floating Point Control Register (FPCR)
  *
  * Exception Enable Byte
@@ -329,7 +281,8 @@ static void fpsr_check_exception(void)
         int vector = 0;
         int vtable[8] = { 49, 49, 50, 51, 53, 52, 54, 48 };
         int i;
-        for (i = 7; i >= 0; i--) {
+               // BSUN is handled separately
+        for (i = 6; i >= 0; i--) {
             if (exception & (1 << i)) {
                 vector = vtable[i];
                 break;
@@ -340,7 +293,6 @@ static void fpsr_check_exception(void)
     }
 }
 
-
 static void fpsr_set_result(fpdata *result)
 {
 #ifdef JIT
@@ -350,14 +302,10 @@ static void fpsr_set_result(fpdata *result)
     regs.fpsr &= 0x00fffff8; // clear cc
     if (fpp_is_nan (result)) {
         regs.fpsr |= FPSR_CC_NAN;
-           // check if result is signaling nan
-               if (fpp_is_snan(result))
-                       regs.fpsr |= FPSR_SNAN;
-    } else {
-        if (fpp_is_zero(result))
-            regs.fpsr |= FPSR_CC_Z;
-        if (fpp_is_infinity (result))
-            regs.fpsr |= FPSR_CC_I;
+       } else if (fpp_is_zero(result)) {
+               regs.fpsr |= FPSR_CC_Z;
+       } else if (fpp_is_infinity (result)) {
+               regs.fpsr |= FPSR_CC_I;
     }
     if (fpp_is_neg(result))
         regs.fpsr |= FPSR_CC_N;
@@ -371,7 +319,7 @@ static void fpsr_clear_status(void)
     fpp_clear_status();
 }
 
-static void fpsr_make_status(void)
+static uae_u32 fpsr_make_status(void)
 {
     // get external status
     fpp_get_status(&regs.fpsr);
@@ -388,7 +336,7 @@ static void fpsr_make_status(void)
     if (regs.fpsr & (FPSR_OVFL | FPSR_INEX2 | FPSR_INEX1))
         regs.fpsr |= FPSR_AE_INEX; // INEX = INEX1 || INEX2 || OVFL
     
-    fpsr_check_exception();
+    return (regs.fpsr & regs.fpcr & (FPSR_SNAN | FPSR_OPERR | FPSR_DZ));
 }
 
 static int fpsr_set_bsun(void)
@@ -429,7 +377,7 @@ static void fpp_set_fpcr (uae_u32 val)
 
 static void fpnan (fpdata *fpd)
 {
-    to_exten(fpd, xhex_nan[0], xhex_nan[1], xhex_nan[2]);
+    fpp_to_exten(fpd, xhex_nan[0], xhex_nan[1], xhex_nan[2]);
 }
 
 static void fpclear (fpdata *fpd)
@@ -531,7 +479,7 @@ bool fpu_get_constant(fpdata *fpd, int cr)
         f[2] += fpp_cr[entry].rndoff[(regs.fpcr >> 4) & 3];
     }
 
-    to_exten_fmovem(fpd, f[0], f[1], f[2]);
+       fpp_to_exten_fmovem(fpd, f[0], f[1], f[2]);
     
     if (((regs.fpcr >> 6) & 3) == 1)
                fpp_roundsgl(fpd);
@@ -967,13 +915,13 @@ static void to_pack (fpdata *fpd, uae_u32 *wrd)
     if (((wrd[0] >> 16) & 0x7fff) == 0x7fff) {
         // infinity has extended exponent and all 0 packed fraction
         // nans are copies bit by bit
-        to_exten_fmovem(fpd, wrd[0], wrd[1], wrd[2]);
+        fpp_to_exten_fmovem(fpd, wrd[0], wrd[1], wrd[2]);
         return;
     }
     if (!(wrd[0] & 0xf) && !wrd[1] && !wrd[2]) {
         // exponent is not cared about, if mantissa is zero
         wrd[0] &= 0x80000000;
-        to_exten_fmovem(fpd, wrd[0], wrd[1], wrd[2]);
+        fpp_to_exten_fmovem(fpd, wrd[0], wrd[1], wrd[2]);
         return;
     }
 
@@ -1024,12 +972,12 @@ static void from_pack (fpdata *src, uae_u32 *wrd, int kfactor)
 
    if (fpp_is_nan (src)) {
         // copied bit by bit, no conversion
-        from_exten(src, &wrd[0], &wrd[1], &wrd[2]);
+        fpp_from_exten_fmovem(src, &wrd[0], &wrd[1], &wrd[2]);
         return;
     }
     if (fpp_is_infinity (src)) {
         // extended exponent and all 0 packed fraction
-        from_exten(src, &wrd[0], &wrd[1], &wrd[2]);
+        fpp_from_exten_fmovem(src, &wrd[0], &wrd[1], &wrd[2]);
         wrd[1] = wrd[2] = 0;
         return;
     }
@@ -1222,7 +1170,7 @@ static int get_fp_value (uae_u32 opcode, uae_u16 extra, fpdata *src, uaecptr old
                                        fpset(src, (uae_s32) m68k_dreg (regs, reg));
                                        break;
                                case 1:
-                                       to_single (src, m68k_dreg (regs, reg));
+                                       fpp_to_single (src, m68k_dreg (regs, reg));
                                        if (normalize_or_fault_if_no_denormal_support_pre(opcode, extra, 0, oldpc, src, 0))
                                                return -1;
                                        break;
@@ -1320,7 +1268,7 @@ static int get_fp_value (uae_u32 opcode, uae_u16 extra, fpdata *src, uaecptr old
                        fpset(src, (uae_s32) (doext ? exts[0] : x_cp_get_long (ad)));
                        break;
                case 1:
-                       to_single (src, (doext ? exts[0] : x_cp_get_long (ad)));
+                       fpp_to_single (src, (doext ? exts[0] : x_cp_get_long (ad)));
                        if (normalize_or_fault_if_no_denormal_support_pre(opcode, extra, 0, oldpc, src, 0))
                                return -1;
                        break;
@@ -1332,7 +1280,7 @@ static int get_fp_value (uae_u32 opcode, uae_u16 extra, fpdata *src, uaecptr old
                                wrd2 = (doext ? exts[1] : x_cp_get_long (ad));
                                ad += 4;
                                wrd3 = (doext ? exts[2] : x_cp_get_long (ad));
-                               to_exten (src, wrd1, wrd2, wrd3);
+                               fpp_to_exten (src, wrd1, wrd2, wrd3);
                                if (normalize_or_fault_if_no_denormal_support_pre(opcode, extra, 0, oldpc, src, 2))
                                        return -1;
                        }
@@ -1365,7 +1313,7 @@ static int get_fp_value (uae_u32 opcode, uae_u16 extra, fpdata *src, uaecptr old
                                wrd1 = (doext ? exts[0] : x_cp_get_long (ad));
                                ad += 4;
                                wrd2 = (doext ? exts[1] : x_cp_get_long (ad));
-                               to_double (src, wrd1, wrd2);
+                               fpp_to_double (src, wrd1, wrd2);
                                if (normalize_or_fault_if_no_denormal_support_pre(opcode, extra, 0, oldpc, src, 1))
                                        return -1;
                        }
@@ -1417,7 +1365,7 @@ static int put_fp_value (fpdata *value, uae_u32 opcode, uae_u16 extra, uaecptr o
                                        m68k_dreg (regs, reg) = (uae_u32)fpp_to_int (value, 2);
                                        break;
                                case 1:
-                                       m68k_dreg (regs, reg) = from_single (value);
+                                       m68k_dreg (regs, reg) = fpp_from_single (value);
                                        break;
                                default:
                                        return 0;
@@ -1486,14 +1434,14 @@ static int put_fp_value (fpdata *value, uae_u32 opcode, uae_u16 extra, uaecptr o
                case 1:
                        if (normalize_or_fault_if_no_denormal_support_pre(opcode, extra, ad, oldpc, value, 2))
                                return -1;
-                       x_cp_put_long(ad, from_single(value));
+                       x_cp_put_long(ad, fpp_from_single(value));
                        break;
                case 2:
                        {
                                uae_u32 wrd1, wrd2, wrd3;
                                if (normalize_or_fault_if_no_denormal_support_pre(opcode, extra, ad, oldpc, value, 2))
                                        return 1;
-                               from_exten(value, &wrd1, &wrd2, &wrd3);
+                               fpp_from_exten(value, &wrd1, &wrd2, &wrd3);
                                x_cp_put_long (ad, wrd1);
                                ad += 4;
                                x_cp_put_long (ad, wrd2);
@@ -1530,7 +1478,7 @@ static int put_fp_value (fpdata *value, uae_u32 opcode, uae_u16 extra, uaecptr o
                                uae_u32 wrd1, wrd2;
                                if (normalize_or_fault_if_no_denormal_support_pre(opcode, extra, ad, oldpc, value, 1))
                                        return -1;
-                               from_double(value, &wrd1, &wrd2);
+                               fpp_from_double(value, &wrd1, &wrd2);
                                x_cp_put_long (ad, wrd1);
                                ad += 4;
                                x_cp_put_long (ad, wrd2);
@@ -1844,7 +1792,7 @@ void fpuop_save (uae_u32 opcode)
                
                if (regs.fpu_exp_state > 1) {
                        uae_u32 src1[3];
-                       from_exten (&regs.exp_src1, &src1[0], &src1[1], &src1[2]);
+                       fpp_from_exten_fmovem (&regs.exp_src1, &src1[0], &src1[1], &src1[2]);
                        frame_id = 0x0000e000 | src1[0];
                        frame_v1 = src1[1];
                        frame_v2 = src1[2];
@@ -1892,8 +1840,8 @@ void fpuop_save (uae_u32 opcode)
                        uae_u32 stag, dtag;
                        uae_u32 extra = regs.exp_extra;
 
-                       from_exten(&regs.exp_src1, &src1[0], &src1[1], &src1[2]);
-                       from_exten(&regs.exp_src2, &src2[0], &src2[1], &src2[2]);
+                       fpp_from_exten_fmovem(&regs.exp_src1, &src1[0], &src1[1], &src1[2]);
+                       fpp_from_exten_fmovem(&regs.exp_src2, &src2[0], &src2[1], &src2[2]);
                        stag = get_ftag(src1[0], src1[1], src1[2], regs.exp_size);
                        dtag = get_ftag(src2[0], src2[1], src2[2], -1);
                        if ((extra & 0x7f) == 4) // FSQRT 4->5
@@ -2106,7 +2054,7 @@ void fpuop_restore (uae_u32 opcode)
                        regs.fpu_exp_state = 0;
                } else if (ff == 0xe0) {
                        regs.fpu_exp_state = 1;
-                       to_exten (&regs.exp_src1, d & 0xffff0000, v1, v2);
+                       fpp_to_exten (&regs.exp_src1, d & 0xffff0000, v1, v2);
                } else if (ff) {
                        write_log (_T("FRESTORE invalid frame format %X!\n"), (d >> 8) & 0xff);
                } else {
@@ -2145,7 +2093,7 @@ static uaecptr fmovem2mem (uaecptr ad, uae_u32 list, int incr, int regdir)
                        else
                                reg = r;
                        if (list & 0x80) {
-                               from_exten(&regs.fp[reg], &wrd[0], &wrd[1], &wrd[2]);
+                               fpp_from_exten_fmovem(&regs.fp[reg], &wrd[0], &wrd[1], &wrd[2]);
                                if (incr < 0)
                                        ad -= 3 * 4;
                                for (int i = 0; i < 3; i++) {
@@ -2174,7 +2122,7 @@ static uaecptr fmovem2mem (uaecptr ad, uae_u32 list, int incr, int regdir)
                        else
                                reg = r;
                        if (list & 0x80) {
-                               from_exten(&regs.fp[reg], &wrd1, &wrd2, &wrd3);
+                               fpp_from_exten_fmovem(&regs.fp[reg], &wrd1, &wrd2, &wrd3);
                                if (incr < 0)
                                        ad -= 3 * 4;
                                x_put_long(ad + 0, wrd1);
@@ -2222,7 +2170,7 @@ static uaecptr fmovem2fpp (uaecptr ad, uae_u32 list, int incr, int regdir)
                                                        mmu030_fmovem_store[i] = wrd[i];
                                                mmu030_state[0]++;
                                                if (i == 2)
-                                                       to_exten (&regs.fp[reg], mmu030_fmovem_store[0], mmu030_fmovem_store[1], wrd[2]);
+                                                       fpp_to_exten (&regs.fp[reg], mmu030_fmovem_store[0], mmu030_fmovem_store[1], wrd[2]);
                                        }
                                }
                                if (incr > 0)
@@ -2246,7 +2194,7 @@ static uaecptr fmovem2fpp (uaecptr ad, uae_u32 list, int incr, int regdir)
                                wrd3 = x_get_long (ad + 8);
                                if (incr > 0)
                                        ad += 3 * 4;
-                               to_exten (&regs.fp[reg], wrd1, wrd2, wrd3);
+                               fpp_to_exten (&regs.fp[reg], wrd1, wrd2, wrd3);
                        }
                        list <<= 1;
                }
@@ -2254,23 +2202,17 @@ static uaecptr fmovem2fpp (uaecptr ad, uae_u32 list, int incr, int regdir)
        return ad;
 }
 
-static bool arithmetic(fpdata *src, int reg, int extra)
+static bool arithmetic(fpdata *src, fpdata *dst, int extra)
 {
        uae_u64 q = 0;
        uae_u8 s = 0;
-       fpdata *dst = &regs.fp[reg];
-
-       // SNAN -> QNAN if SNAN interrupt is not enabled
-       if (fpp_is_snan(src) && !(regs.fpcr & 0x4000)) {
-        fpp_unset_snan(src);
-       }
 
        switch (extra & 0x7f)
        {
                case 0x00: /* FMOVE */
                case 0x40:
                case 0x44:
-                       *dst = *src;
+                       fpp_move(src, dst);
                        break;
                case 0x01: /* FINT */
                        fpp_int(src, dst);
@@ -2360,6 +2302,8 @@ static bool arithmetic(fpdata *src, int reg, int extra)
                        break;
                case 0x21: /* FMOD */
                        fpp_mod(dst, src, &q, &s);
+                       if (fpsr_make_status())
+                               return false;
                        fpsr_set_quotient(q, s);
                        break;
                case 0x22: /* FADD */
@@ -2374,10 +2318,14 @@ static bool arithmetic(fpdata *src, int reg, int extra)
                        break;
                case 0x24: /* FSGLDIV */
                        fpp_sgldiv(dst, src);
+                       if (fpsr_make_status())
+                               return false;
                        fpsr_set_result(dst);
                        return true;
                case 0x25: /* FREM */
                        fpp_rem(dst, src, &q, &s);
+                       if (fpsr_make_status())
+                               return false;
                        fpsr_set_quotient(q, s);
                        break;
                case 0x26: /* FSCALE */
@@ -2385,6 +2333,8 @@ static bool arithmetic(fpdata *src, int reg, int extra)
                        break;
                case 0x27: /* FSGLMUL */
                        fpp_sglmul(dst, src);
+                       if (fpsr_make_status())
+                               return false;
                        fpsr_set_result(dst);
                        return true;
                case 0x28: /* FSUB */
@@ -2400,26 +2350,32 @@ static bool arithmetic(fpdata *src, int reg, int extra)
                case 0x35: /* FSINCOS */
                case 0x36: /* FSINCOS */
                case 0x37: /* FSINCOS */
-                       fpp_cos(src, &regs.fp[extra & 7]);
-                       fpp_sin(src, dst);
+                       fpp_cos(src, dst);
             if (((regs.fpcr >> 6) & 3) == 1)
-                               fpp_round32(&regs.fp[extra & 7]);
+                               fpp_round32(dst);
             else if (((regs.fpcr >> 6) & 3) == 2)
-                               fpp_round64(&regs.fp[extra & 7]);
+                               fpp_round64(dst);
+                       regs.fp[extra & 7] = *dst;
+                       fpp_sin(src, dst);
                        break;
                case 0x38: /* FCMP */
                {
-                       fpdata v = *dst;
-                       fpp_cmp(&v, src);
-                       fpsr_set_result(&v);
-                       return true;
+                       fpp_cmp(dst, src);
+                       if (fpsr_make_status())
+                               return false;
+                       fpsr_set_result(dst);
+                       return false;
                }
                case 0x3a: /* FTST */
                {
-                       fpsr_set_result(src);
-                       return true;
+                       fpp_tst(dst, src);
+                       if (fpsr_make_status())
+                               return false;
+                       fpsr_set_result(dst);
+                       return false;
                }
                default:
+                       write_log (_T("Unknown FPU arithmetic function (%02x)\n"), extra & 0x7f);
                        return false;
        }
 
@@ -2434,6 +2390,9 @@ static bool arithmetic(fpdata *src, int reg, int extra)
         fpp_round64(dst);
        }
 
+       if (fpsr_make_status())
+               return false;
+
        fpsr_set_result(dst);
        return true;
 }
@@ -2442,7 +2401,7 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra)
 {
        int reg = -1;
        int v;
-       fpdata srcd;
+       fpdata src, dst;
        uaecptr pc = m68k_getpc () - 4;
        uaecptr ad = 0;
 
@@ -2657,7 +2616,7 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra)
                        if ((extra & 0xfc00) == 0x5c00) {
                                if (fault_if_no_fpu (opcode, extra, 0, pc))
                                        return;
-                               if (fault_if_unimplemented_680x0 (opcode, extra, ad, pc, &srcd, reg))
+                               if (fault_if_unimplemented_680x0 (opcode, extra, ad, pc, &src, reg))
                                        return;
                                fpsr_clear_status();
                                fpu_get_constant(&regs.fp[reg], extra);
@@ -2669,7 +2628,9 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra)
                        if (fault_if_unimplemented_6888x (opcode, extra, pc))
                                return;
 
-                       v = get_fp_value (opcode, extra, &srcd, pc, &ad);
+                       fpsr_clear_status();
+
+                       v = get_fp_value (opcode, extra, &src, pc, &ad);
                        if (v <= 0) {
                                if (v == 0)
                                        fpu_noinst (opcode, pc);
@@ -2677,21 +2638,23 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra)
                        }
 
                        // get_fp_value() checked this, but only if EA was nonzero (non-register)
-                       if (fault_if_unimplemented_680x0 (opcode, extra, ad, pc, &srcd, reg))
+                       if (fault_if_unimplemented_680x0 (opcode, extra, ad, pc, &src, reg))
                                return;
 
                        regs.fpiar =  pc;
 
+                       dst = regs.fp[reg];
+
                        if((extra & 0x30) == 0x20 || (extra & 0x7f) == 0x38) { // dyadic operation
-                               if(normalize_or_fault_if_no_denormal_support_pre(opcode, extra, ad, pc, &regs.fp[reg], 2))
+                               if(normalize_or_fault_if_no_denormal_support_pre(opcode, extra, ad, pc, &dst, 2))
                                        return;
                        }
 
                        fpsr_clear_status();
-                       v = arithmetic(&srcd, reg, extra);
-                       if (!v)
-                               fpu_noinst (opcode, pc);
-                       fpsr_make_status();
+                       v = arithmetic(&src, &dst, extra);
+                       if (v)
+                               regs.fp[reg] = dst;
+                       fpsr_check_exception();
                        return;
                default:
                break;
@@ -2758,7 +2721,7 @@ uae_u8 *restore_fpu (uae_u8 *src)
                w1 = restore_u16 () << 16;
                w2 = restore_u32 ();
                w3 = restore_u32 ();
-               to_exten (&regs.fp[i], w1, w2, w3);
+               fpp_to_exten_fmovem(&regs.fp[i], w1, w2, w3);
        }
        regs.fpcr = restore_u32 ();
        regs.fpsr = restore_u32 ();
@@ -2772,11 +2735,11 @@ uae_u8 *restore_fpu (uae_u8 *src)
                w1 = restore_u16() << 16;
                w2 = restore_u32();
                w3 = restore_u32();
-               to_exten(&regs.exp_src1, w1, w2, w3);
+               fpp_to_exten_fmovem(&regs.exp_src1, w1, w2, w3);
                w1 = restore_u16() << 16;
                w2 = restore_u32();
                w3 = restore_u32();
-               to_exten(&regs.exp_src2, w1, w2, w3);
+               fpp_to_exten_fmovem(&regs.exp_src2, w1, w2, w3);
                regs.exp_pack[0] = restore_u32();
                regs.exp_pack[1] = restore_u32();
                regs.exp_pack[2] = restore_u32();
@@ -2808,7 +2771,7 @@ uae_u8 *save_fpu (int *len, uae_u8 *dstptr)
        save_u32 (currprefs.fpu_model);
        save_u32 (0x80000000 | 0x40000000 | (regs.fpu_state == 0 ? 1 : 0) | (regs.fpu_exp_state ? 2 : 0) | (regs.fpu_exp_state > 1 ? 4 : 0));
        for (i = 0; i < 8; i++) {
-               from_exten (&regs.fp[i], &w1, &w2, &w3);
+               fpp_from_exten_fmovem(&regs.fp[i], &w1, &w2, &w3);
                save_u16 (w1 >> 16);
                save_u32 (w2);
                save_u32 (w3);
@@ -2820,11 +2783,11 @@ uae_u8 *save_fpu (int *len, uae_u8 *dstptr)
        save_u32 (-1);
        save_u32 (0);
 
-       from_exten(&regs.exp_src1, &w1, &w2, &w3);
+       fpp_from_exten_fmovem(&regs.exp_src1, &w1, &w2, &w3);
        save_u16(w1 >> 16);
        save_u32(w2);
        save_u32(w3);
-       from_exten(&regs.exp_src2, &w1, &w2, &w3);
+       fpp_from_exten_fmovem(&regs.exp_src2, &w1, &w2, &w3);
        save_u16(w1 >> 16);
        save_u32(w2);
        save_u32(w3);
index 87455467ab98fd078531bb4e881aa0425e7890e4..c9fcf2fac921f3f9de95145150d6f7937b0323c0 100644 (file)
@@ -323,7 +323,7 @@ static void fp_from_native(fptype fp, fpdata *fpd)
     fpd->fp = fp;
 }
 
-static void fp_to_single_xn(fpdata *fpd, uae_u32 wrd1)
+static void fp_to_single(fpdata *fpd, uae_u32 wrd1)
 {
     union {
         float f;
@@ -333,17 +333,7 @@ static void fp_to_single_xn(fpdata *fpd, uae_u32 wrd1)
     val.u = wrd1;
     fpd->fp = (fptype) val.f;
 }
-static void fp_to_single_x(fpdata *fpd, uae_u32 wrd1)
-{
-    union {
-        float f;
-        uae_u32 u;
-    } val;
-    
-    val.u = wrd1;
-    fpd->fp = (fptype) val.f;
-}
-static uae_u32 fp_from_single_x(fpdata *fpd)
+static uae_u32 fp_from_single(fpdata *fpd)
 {
     union {
         float f;
@@ -354,23 +344,7 @@ static uae_u32 fp_from_single_x(fpdata *fpd)
     return val.u;
 }
 
-static void fp_to_double_xn(fpdata *fpd, uae_u32 wrd1, uae_u32 wrd2)
-{
-    union {
-        double d;
-        uae_u32 u[2];
-    } val;
-    
-#ifdef WORDS_BIGENDIAN
-    val.u[0] = wrd1;
-    val.u[1] = wrd2;
-#else
-    val.u[1] = wrd1;
-    val.u[0] = wrd2;
-#endif
-    fpd->fp = (fptype) val.d;
-}
-static void fp_to_double_x(fpdata *fpd, uae_u32 wrd1, uae_u32 wrd2)
+static void fp_to_double(fpdata *fpd, uae_u32 wrd1, uae_u32 wrd2)
 {
     union {
         double d;
@@ -386,7 +360,7 @@ static void fp_to_double_x(fpdata *fpd, uae_u32 wrd1, uae_u32 wrd2)
 #endif
     fpd->fp = (fptype) val.d;
 }
-static void fp_from_double_x(fpdata *fpd, uae_u32 *wrd1, uae_u32 *wrd2)
+static void fp_from_double(fpdata *fpd, uae_u32 *wrd1, uae_u32 *wrd2)
 {
     union {
         double d;
@@ -403,7 +377,7 @@ static void fp_from_double_x(fpdata *fpd, uae_u32 *wrd1, uae_u32 *wrd2)
 #endif
 }
 #ifdef USE_LONG_DOUBLE
-static void fp_to_exten_x(fpdata *fpd, uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3)
+static void fp_to_exten(fpdata *fpd, uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3)
 {
     union {
         long double ld;
@@ -421,7 +395,7 @@ static void fp_to_exten_x(fpdata *fpd, uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3)
 #endif
     fpd->fp = val.ld;
 }
-static void fp_from_exten_x(fpdata *fpd, uae_u32 *wrd1, uae_u32 *wrd2, uae_u32 *wrd3)
+static void fp_from_exten(fpdata *fpd, uae_u32 *wrd1, uae_u32 *wrd2, uae_u32 *wrd3)
 {
     union {
         long double ld;
@@ -440,14 +414,14 @@ static void fp_from_exten_x(fpdata *fpd, uae_u32 *wrd1, uae_u32 *wrd2, uae_u32 *
 #endif
 }
 #else // if !USE_LONG_DOUBLE
-static void fp_to_exten_x(fpdata *fpd, uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3)
+static void fp_to_exten(fpdata *fpd, uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3)
 {
 #if 1
        floatx80 fx80;
        fx80.high = wrd1 >> 16;
        fx80.low = (((uae_u64)wrd2) << 32) | wrd3;
        float64 f = floatx80_to_float64(fx80, &fs);
-       fp_to_double_x(fpd, f >> 32, (uae_u32)f);
+       fp_to_double(fpd, f >> 32, (uae_u32)f);
 #else
     double frac;
     if ((wrd1 & 0x7fff0000) == 0 && wrd2 == 0 && wrd3 == 0) {
@@ -460,11 +434,11 @@ static void fp_to_exten_x(fpdata *fpd, uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3)
     fpd->fp = ldexp (frac, ((wrd1 >> 16) & 0x7fff) - 16383);
 #endif
 }
-static void fp_from_exten_x(fpdata *fpd, uae_u32 *wrd1, uae_u32 *wrd2, uae_u32 *wrd3)
+static void fp_from_exten(fpdata *fpd, uae_u32 *wrd1, uae_u32 *wrd2, uae_u32 *wrd3)
 {
 #if 1
        uae_u32 w1, w2;
-       fp_from_double_x(fpd, &w1, &w2);
+       fp_from_double(fpd, &w1, &w2);
        floatx80 f = float64_to_floatx80(((uae_u64)w1 << 32) | w2, &fs);
        *wrd1 = f.high << 16;
        *wrd2 = f.low >> 32;
@@ -512,7 +486,7 @@ static uae_s64 fp_to_int(fpdata *src, int size)
        fptype fp = src->fp;
        if (fp_is_nan(src)) {
                uae_u32 w1, w2, w3;
-               fp_from_exten_x(src, &w1, &w2, &w3);
+               fp_from_exten(src, &w1, &w2, &w3);
                uae_s64 v = 0;
                fpsr_set_exception(FPSR_OPERR);
                // return mantissa
@@ -924,6 +898,16 @@ static void fp_cmp(fpdata *a, fpdata *b)
        a->fp = v;
 }
 
+static void fp_tst(fpdata *a, fpdata *b)
+{
+       a->fpx = b->fpx;
+}
+
+static void fp_move(fpdata *src, fpdata *dst)
+{
+       dst->fp = src->fp;
+}
+
 void fp_init_native(void)
 {
        set_floatx80_rounding_precision(80, &fs);
@@ -949,16 +933,14 @@ void fp_init_native(void)
        fpp_to_int = fp_to_int;
        fpp_from_int = fp_from_int;
 
-       fpp_to_single_xn = fp_to_single_xn;
-       fpp_to_single_x = fp_to_single_x;
-       fpp_from_single_x = fp_from_single_x;
-
-       fpp_to_double_xn = fp_to_double_xn;
-       fpp_to_double_x = fp_to_double_x;
-       fpp_from_double_x = fp_from_double_x;
-
-       fpp_to_exten_x = fp_to_exten_x;
-       fpp_from_exten_x = fp_from_exten_x;
+       fpp_to_single = fp_to_single;
+       fpp_from_single = fp_from_single;
+       fpp_to_double = fp_to_double;
+       fpp_from_double = fp_from_double;
+       fpp_to_exten = fp_to_exten;
+       fpp_from_exten = fp_from_exten;
+       fpp_to_exten_fmovem = fp_to_exten;
+       fpp_from_exten_fmovem = fp_from_exten;
 
        fpp_roundsgl = fp_roundsgl;
        fpp_rounddbl = fp_rounddbl;
@@ -1002,4 +984,6 @@ void fp_init_native(void)
        fpp_sgldiv = fp_sgldiv;
        fpp_sglmul = fp_sglmul;
        fpp_cmp = fp_cmp;
+       fpp_tst = fp_tst;
+       fpp_move = fp_move;
 }
index 00d11fd0e908f7620947097e28997f177e978dd8..af4843f0e2d3afd9a3b74c95ac3e8c319d8a7b3c 100644 (file)
@@ -7,7 +7,6 @@
 * Andreas Grabher and Toni Wilen
 *
 */
-
 #define __USE_ISOC9X  /* We might be able to pick up a NaN */
 
 #define SOFTFLOAT_FAST_INT64
@@ -64,16 +63,20 @@ static void fp_set_mode(uae_u32 mode_control)
 
 static void fp_get_status(uae_u32 *status)
 {
-    if (fs.float_exception_flags & float_flag_invalid)
-        *status |= 0x2000;
-    if (fs.float_exception_flags & float_flag_divbyzero)
-        *status |= 0x0400;
-    if (fs.float_exception_flags & float_flag_overflow)
-        *status |= 0x1000;
-    if (fs.float_exception_flags & float_flag_underflow)
-        *status |= 0x0800;
-    if (fs.float_exception_flags & float_flag_inexact)
-        *status |= 0x0200;
+       if (fs.float_exception_flags & float_flag_signaling) {
+               *status |= FPSR_SNAN;
+       } else {
+               if (fs.float_exception_flags & float_flag_invalid)
+                       *status |= FPSR_OPERR;
+               if (fs.float_exception_flags & float_flag_divbyzero)
+                       *status |= FPSR_DZ;
+               if (fs.float_exception_flags & float_flag_overflow)
+                       *status |= FPSR_OVFL;
+               if (fs.float_exception_flags & float_flag_underflow)
+                       *status |= FPSR_UNFL;
+               if (fs.float_exception_flags & float_flag_inexact)
+                       *status |= FPSR_INEX2;
+       }
 }
 STATIC_INLINE void fp_clear_status(void)
 {
@@ -122,19 +125,6 @@ static const TCHAR *fp_print(fpdata *fpd)
        return fsout;
 }
 
-static void softfloat_set(fpdata *fpd, uae_u32 *f)
-{
-    fpd->fpx.high = (uae_u16)(f[0] >> 16);
-    fpd->fpx.low = ((uae_u64)f[1] << 32) | f[2];
-}
-
-static void softfloat_get(fpdata *fpd, uae_u32 *f)
-{
-    f[0] = (uae_u32)(fpd->fpx.high << 16);
-    f[1] = fpd->fpx.low >> 32;
-    f[2] = (uae_u32)fpd->fpx.low;
-}
-
 /* Functions for detecting float type */
 static bool fp_is_snan(fpdata *fpd)
 {
@@ -283,52 +273,53 @@ static void from_native(fptype fp, fpdata *fpd)
     }
 }
 
-static void to_single_xn(fpdata *fpd, uae_u32 wrd1)
-{
-    float32 f = wrd1;
-    fpd->fpx = float32_to_floatx80(f, &fs); // automatically fix denormals
-}
-static void to_single_x(fpdata *fpd, uae_u32 wrd1)
+static void to_single(fpdata *fpd, uae_u32 wrd1)
 {
     float32 f = wrd1;
     fpd->fpx = float32_to_floatx80_allowunnormal(f, &fs);
 }
-static uae_u32 from_single_x(fpdata *fpd)
+static uae_u32 from_single(fpdata *fpd)
 {
     float32 f = floatx80_to_float32(fpd->fpx, &fs);
     return f;
 }
 
-static void to_double_xn(fpdata *fpd, uae_u32 wrd1, uae_u32 wrd2)
-{
-    float64 f = ((float64)wrd1 << 32) | wrd2;
-    fpd->fpx = float64_to_floatx80(f, &fs); // automatically fix denormals
-}
-static void to_double_x(fpdata *fpd, uae_u32 wrd1, uae_u32 wrd2)
+static void to_double(fpdata *fpd, uae_u32 wrd1, uae_u32 wrd2)
 {
     float64 f = ((float64)wrd1 << 32) | wrd2;
     fpd->fpx = float64_to_floatx80_allowunnormal(f, &fs);
 }
-static void from_double_x(fpdata *fpd, uae_u32 *wrd1, uae_u32 *wrd2)
+static void from_double(fpdata *fpd, uae_u32 *wrd1, uae_u32 *wrd2)
 {
     float64 f = floatx80_to_float64(fpd->fpx, &fs);
     *wrd1 = f >> 32;
     *wrd2 = (uae_u32)f;
 }
 
-static void to_exten_x(fpdata *fpd, uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3)
+static void to_exten(fpdata *fpd, uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3)
+{
+       fpd->fpx.high = (uae_u16)(wrd1 >> 16);
+       fpd->fpx.low = ((uae_u64)wrd2 << 32) | wrd3;
+}
+static void from_exten(fpdata *fpd, uae_u32 *wrd1, uae_u32 *wrd2, uae_u32 *wrd3)
 {
-    uae_u32 wrd[3] = { wrd1, wrd2, wrd3 };
-    softfloat_set(fpd, wrd);
+       floatx80 f = floatx80_to_floatx80(fpd->fpx, &fs);
+       *wrd1 = (uae_u32)(f.high << 16);
+       *wrd2 = f.low >> 32;
+       *wrd3 = (uae_u32)f.low;
 }
-static void from_exten_x(fpdata *fpd, uae_u32 *wrd1, uae_u32 *wrd2, uae_u32 *wrd3)
+
+static void to_exten_fmovem(fpdata *fpd, uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3)
 {
-    uae_u32 wrd[3];
-    softfloat_get(fpd, wrd);
-    *wrd1 = wrd[0];
-    *wrd2 = wrd[1];
-    *wrd3 = wrd[2];
+       fpd->fpx.high = (uae_u16)(wrd1 >> 16);
+       fpd->fpx.low = ((uae_u64)wrd2 << 32) | wrd3;
 }
+static void from_exten_fmovem(fpdata *fpd, uae_u32 *wrd1, uae_u32 *wrd2, uae_u32 *wrd3)
+ {
+       *wrd1 = (uae_u32)(fpd->fpx.high << 16);
+       *wrd2 = fpd->fpx.low >> 32;
+       *wrd3 = (uae_u32)fpd->fpx.low;
+ }
 
 static uae_s64 to_int(fpdata *src, int size)
 {
@@ -370,6 +361,8 @@ static void fp_rounddbl(fpdata *fpd)
 // round to float
 static void fp_round32(fpdata *fpd)
 {
+       if (fp_is_nan(fpd))
+               return;
     float32 f = floatx80_to_float32(fpd->fpx, &fs);
     fpd->fpx = float32_to_floatx80(f, &fs);
 }
@@ -377,12 +370,19 @@ static void fp_round32(fpdata *fpd)
 // round to double
 static void fp_round64(fpdata *fpd)
 {
+       if (fp_is_nan(fpd))
+               return;
     float64 f = floatx80_to_float64(fpd->fpx, &fs);
     fpd->fpx = float64_to_floatx80(f, &fs);
 }
 
 /* Arithmetic functions */
 
+static void fp_move(fpdata *src, fpdata *dst)
+{
+    dst->fpx = floatx80_move(src->fpx, &fs);
+}
+
 static void fp_int(fpdata *a, fpdata *dst)
 {
     dst->fpx = floatx80_round_to_int(a->fpx, &fs);
@@ -516,6 +516,10 @@ static void fp_cmp(fpdata *a, fpdata *b)
 {
     a->fpx = floatx80_cmp(a->fpx, b->fpx, &fs);
 }
+static void fp_tst(fpdata *a, fpdata *b)
+{
+       a->fpx = floatx80_tst(b->fpx, &fs);
+}
 
 /* FIXME: create softfloat functions for following arithmetics */
 
@@ -628,16 +632,14 @@ void fp_init_softfloat(void)
        fpp_to_int = to_int;
        fpp_from_int = from_int;
 
-       fpp_to_single_xn = to_single_xn;
-       fpp_to_single_x = to_single_x;
-       fpp_from_single_x = from_single_x;
-
-       fpp_to_double_xn = to_double_xn;
-       fpp_to_double_x = to_double_x;
-       fpp_from_double_x = from_double_x;
-
-       fpp_to_exten_x = to_exten_x;
-       fpp_from_exten_x = from_exten_x;
+       fpp_to_single = to_single;
+       fpp_from_single = from_single;
+       fpp_to_double = to_double;
+       fpp_from_double = from_double;
+       fpp_to_exten = to_exten;
+       fpp_from_exten = from_exten;
+       fpp_to_exten_fmovem = to_exten_fmovem;
+       fpp_from_exten_fmovem = from_exten_fmovem;
 
        fpp_roundsgl = fp_roundsgl;
        fpp_rounddbl = fp_rounddbl;
@@ -681,5 +683,7 @@ void fp_init_softfloat(void)
        fpp_sgldiv = fp_sgldiv;
        fpp_sglmul = fp_sglmul;
        fpp_cmp = fp_cmp;
+       fpp_tst = fp_tst;
+       fpp_move = fp_move;
 }
 
index 434059eff5f1488d6cc4eccad02590988e2904e0..8a952bbfde539f82659add7727b919421f635159 100644 (file)
@@ -16,10 +16,6 @@ extern void fpsr_set_exception(uae_u32 exception);
 extern void init_fpucw_x87(void);
 #endif
 
-void to_single(fpdata *fpd, uae_u32 wrd1);
-void to_double(fpdata *fpd, uae_u32 wrd1, uae_u32 wrd2);
-void to_exten(fpdata *fpd, uae_u32 wrd1, uae_u32 wrd2, uae_u32 wrd3);
-
 typedef void (*FPP_ABQS)(fpdata*, fpdata*, uae_u64*, uae_u8*);
 typedef void (*FPP_AB)(fpdata*, fpdata*);
 typedef void (*FPP_A)(fpdata*);
@@ -67,16 +63,14 @@ extern FPP_TO_NATIVE fpp_to_native;
 extern FPP_TO_INT fpp_to_int;
 extern FPP_FROM_INT fpp_from_int;
 
-extern FPP_TO_SINGLE fpp_to_single_xn;
-extern FPP_TO_SINGLE fpp_to_single_x;
-extern FPP_FROM_SINGLE fpp_from_single_x;
-
-extern FPP_TO_DOUBLE fpp_to_double_xn;
-extern FPP_TO_DOUBLE fpp_to_double_x;
-extern FPP_FROM_DOUBLE fpp_from_double_x;
-
-extern FPP_TO_EXTEN fpp_to_exten_x;
-extern FPP_FROM_EXTEN fpp_from_exten_x;
+extern FPP_TO_SINGLE fpp_to_single;
+extern FPP_FROM_SINGLE fpp_from_single;
+extern FPP_TO_DOUBLE fpp_to_double;
+extern FPP_FROM_DOUBLE fpp_from_double;
+extern FPP_TO_EXTEN fpp_to_exten;
+extern FPP_FROM_EXTEN fpp_from_exten;
+extern FPP_TO_EXTEN fpp_to_exten_fmovem;
+extern FPP_FROM_EXTEN fpp_from_exten_fmovem;
 
 extern FPP_A fpp_roundsgl;
 extern FPP_A fpp_rounddbl;
@@ -120,3 +114,5 @@ extern FPP_AB fpp_sub;
 extern FPP_AB fpp_sgldiv;
 extern FPP_AB fpp_sglmul;
 extern FPP_AB fpp_cmp;
+extern FPP_AB fpp_tst;
+extern FPP_AB fpp_move;
index a24dc90f3e959fdd78714669d43b111614720229..4883d1a87be46ccf185aea1068c500cc9fa8db42 100644 (file)
@@ -422,7 +422,7 @@ float32 float32_squash_input_denormal(float32 a, float_status *status)
 {
     if (status->flush_inputs_to_zero) {
         if (extractFloat32Exp(a) == 0 && extractFloat32Frac(a) != 0) {
-            float_raise(float_flag_input_denormal, status);
+            //float_raise(float_flag_input_denormal, status);
             return make_float32(float32_val(a) & 0x80000000);
         }
     }
@@ -527,7 +527,7 @@ static float32 roundAndPackFloat32(flag zSign, int zExp, uint32_t zSig,
         }
         if ( zExp < 0 ) {
             if (status->flush_to_zero) {
-                float_raise(float_flag_output_denormal, status);
+                //float_raise(float_flag_output_denormal, status);
                 return packFloat32(zSign, 0, 0);
             }
             isTiny =
@@ -615,7 +615,7 @@ float64 float64_squash_input_denormal(float64 a, float_status *status)
 {
     if (status->flush_inputs_to_zero) {
         if (extractFloat64Exp(a) == 0 && extractFloat64Frac(a) != 0) {
-            float_raise(float_flag_input_denormal, status);
+            //float_raise(float_flag_input_denormal, status);
             return make_float64(float64_val(a) & (1ULL << 63));
         }
     }
@@ -719,7 +719,7 @@ static float64 roundAndPackFloat64(flag zSign, int zExp, uint64_t zSig,
         }
         if ( zExp < 0 ) {
             if (status->flush_to_zero) {
-                float_raise(float_flag_output_denormal, status);
+                //float_raise(float_flag_output_denormal, status);
                 return packFloat64(zSign, 0, 0);
             }
             isTiny =
@@ -918,7 +918,7 @@ static floatx80 roundAndPackFloatx80(int8_t roundingPrecision, flag zSign,
                if ( zExp <= 0 ) {
 #endif
             if (status->flush_to_zero) {
-                float_raise(float_flag_output_denormal, status);
+                //float_raise(float_flag_output_denormal, status);
                 return packFloatx80(zSign, 0, 0);
             }
             isTiny =
@@ -1385,7 +1385,7 @@ static float128 roundAndPackFloat128(flag zSign, int32_t zExp,
         }
         if ( zExp < 0 ) {
             if (status->flush_to_zero) {
-                float_raise(float_flag_output_denormal, status);
+                //float_raise(float_flag_output_denormal, status);
                 return packFloat128(zSign, 0, 0, 0);
             }
             isTiny =
@@ -2069,10 +2069,8 @@ floatx80 float32_to_floatx80(float32 a, float_status *status)
     aExp = extractFloat32Exp( a );
     aSign = extractFloat32Sign( a );
     if ( aExp == 0xFF ) {
-        if (aSig) {
-            return commonNaNToFloatx80(float32ToCommonNaN(a, status), status);
-        }
-        return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+        aSig |= 0x00800000;
+        return packFloatx80( aSign, 0x7FFF, ( (uint64_t) aSig )<<40 );
     }
     if ( aExp == 0 ) {
         if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
@@ -2283,9 +2281,9 @@ static float32 addFloat32Sigs(float32 a, float32 b, flag zSign,
         }
         if ( aExp == 0 ) {
             if (status->flush_to_zero) {
-                if (aSig | bSig) {
-                    float_raise(float_flag_output_denormal, status);
-                }
+//                if (aSig | bSig) {
+//                    float_raise(float_flag_output_denormal, status);
+//                }
                 return packFloat32(zSign, 0, 0);
             }
             return packFloat32( zSign, 0, ( aSig + bSig )>>6 );
@@ -2769,7 +2767,7 @@ float32 float32_muladd(float32 a, float32 b, float32 c, int flags,
             }
             /* Exact zero plus a denorm */
             if (status->flush_to_zero) {
-                float_raise(float_flag_output_denormal, status);
+                //float_raise(float_flag_output_denormal, status);
                 return packFloat32(cSign ^ signflip, 0, 0);
             }
         }
@@ -3874,10 +3872,7 @@ floatx80 float64_to_floatx80(float64 a, float_status *status)
     aExp = extractFloat64Exp( a );
     aSign = extractFloat64Sign( a );
     if ( aExp == 0x7FF ) {
-        if (aSig) {
-            return commonNaNToFloatx80(float64ToCommonNaN(a, status), status);
-        }
-        return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
+        return packFloatx80( aSign, 0x7FFF, ( aSig | LIT64( 0x0010000000000000 ) )<<11 );
     }
     if ( aExp == 0 ) {
         if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
@@ -4103,9 +4098,9 @@ static float64 addFloat64Sigs(float64 a, float64 b, flag zSign,
         }
         if ( aExp == 0 ) {
             if (status->flush_to_zero) {
-                if (aSig | bSig) {
-                    float_raise(float_flag_output_denormal, status);
-                }
+//                if (aSig | bSig) {
+//                    float_raise(float_flag_output_denormal, status);
+//                }
                 return packFloat64(zSign, 0, 0);
             }
             return packFloat64( zSign, 0, ( aSig + bSig )>>9 );
@@ -4580,7 +4575,7 @@ float64 float64_muladd(float64 a, float64 b, float64 c, int flags,
             }
             /* Exact zero plus a denorm */
             if (status->flush_to_zero) {
-                float_raise(float_flag_output_denormal, status);
+//                float_raise(float_flag_output_denormal, status);
                 return packFloat64(cSign ^ signflip, 0, 0);
             }
         }
@@ -5345,6 +5340,35 @@ float64 floatx80_to_float64(floatx80 a, float_status *status)
 
 }
 
+#ifdef SOFTFLOAT_68K // 31-01-2017
+/*----------------------------------------------------------------------------
+ | Returns the result of converting the extended double-precision floating-
+ | point value `a' to the extended double-precision floating-point format.
+ | The conversion is performed according to the IEC/IEEE Standard for Binary
+ | Floating-Point Arithmetic.
+ *----------------------------------------------------------------------------*/
+        
+floatx80 floatx80_to_floatx80( floatx80 a, float_status *status )
+{
+    flag aSign;
+    int32_t aExp;
+    uint64_t aSig;
+    
+    aSig = extractFloatx80Frac( a );
+    aExp = extractFloatx80Exp( a );
+    aSign = extractFloatx80Sign( a );
+    
+    if ( aExp == 0x7FFF && (uint64_t) ( aSig<<1 ) ) {
+        return propagateFloatx80NaN( a, a, status );
+    }
+    if ( aExp == 0 && aSig != 0 ) {
+        return normalizeRoundAndPackFloatx80( status->floatx80_rounding_precision, aSign, aExp, aSig, 0, status );
+    }
+    return a;
+    
+}
+#endif
+
 /*----------------------------------------------------------------------------
 | Returns the result of converting the extended double-precision floating-
 | point value `a' to the quadruple-precision floating-point format.  The
@@ -5424,12 +5448,9 @@ floatx80 floatx80_normalize( floatx80 a )
     
     shiftCount = countLeadingZeros64( aSig );
     
-    if ( shiftCount > aExp ) {
-        shiftCount = aExp;
-        aExp = 0;
-    } else {
-        aExp -= shiftCount;
-    }
+    if ( shiftCount > aExp ) shiftCount = aExp;
+    
+    aExp -= shiftCount;
     aSig <<= shiftCount;
     
     return packFloatx80( aSign, aExp, aSig );
@@ -6578,6 +6599,8 @@ floatx80 floatx80_cmp( floatx80 a, floatx80 b, float_status *status )
     
     if ( ( aExp == 0x7FFF && (uint64_t) ( aSig<<1 ) ) ||
          ( bExp == 0x7FFF && (uint64_t) ( bSig<<1 ) ) ) {
+        if ( floatx80_is_signaling_nan( a, status ) || floatx80_is_signaling_nan( b, status ) )
+            float_raise( float_flag_signaling, status );
                return packFloatx80(0, 0x7FFF, floatx80_default_nan_low);    }
     
     if ( bExp < aExp ) return packFloatx80( aSign, 0x3FFF, LIT64( 0x8000000000000000 ) );
@@ -6598,7 +6621,35 @@ floatx80 floatx80_cmp( floatx80 a, floatx80 b, float_status *status )
     return packFloatx80( aSign, 0x3FFF, LIT64( 0x8000000000000000 ) );
     
 }
+
+floatx80 floatx80_tst( floatx80 a, float_status *status )
+{
+    if ( floatx80_is_signaling_nan( a, status ) )
+        float_raise( float_flag_signaling, status );
+    return a;
+}
+
+floatx80 floatx80_move( floatx80 a, float_status *status )
+{
+    flag aSign;
+    int32_t aExp;
+    uint64_t aSig;
     
+    aSig = extractFloatx80Frac( a );
+    aExp = extractFloatx80Exp( a );
+    aSign = extractFloatx80Sign( a );
+    
+    if ( aExp == 0x7FFF ) {
+        if ( (uint64_t) ( aSig<<1 ) ) return propagateFloatx80NaN( a, a, status );
+        return a;
+    }
+    if ( aExp == 0 ) {
+        if ( aSig == 0 ) return a;
+        normalizeRoundAndPackFloatx80( status->floatx80_rounding_precision, aSign, aExp, aSig, 0, status );
+    }
+    return a;
+}
+
 #endif // End of addition for Previous
 
 /*----------------------------------------------------------------------------
index f5f1c4707d9ff10fce2f79a6bea19d7acbdd2953..6dfaf616ebdeb0183a9c3e446511d4fc8b7f5cd1 100644 (file)
@@ -194,8 +194,9 @@ enum {
     float_flag_overflow  =  8,
     float_flag_underflow = 16,
     float_flag_inexact   = 32,
-    float_flag_input_denormal = 64,
-    float_flag_output_denormal = 128
+       float_flag_signaling = 64
+//    float_flag_input_denormal = 64,
+//    float_flag_output_denormal = 128
 };
 
 typedef struct float_status {
@@ -605,6 +606,9 @@ int64_t floatx80_to_int64(floatx80, float_status *status);
 int64_t floatx80_to_int64_round_to_zero(floatx80, float_status *status);
 float32 floatx80_to_float32(floatx80, float_status *status);
 float64 floatx80_to_float64(floatx80, float_status *status);
+#ifdef SOFTFLOAT_68K
+floatx80 floatx80_to_floatx80( floatx80, float_status *status);
+#endif
 float128 floatx80_to_float128(floatx80, float_status *status);
 
 floatx80 floatx80_round_to_int_toward_zero( floatx80 a, float_status *status);
@@ -629,6 +633,8 @@ floatx80 floatx80_scale(floatx80 a, floatx80 b, float_status *status);
 floatx80 floatx80_sglmul( floatx80 a, floatx80 b, float_status *status);
 floatx80 floatx80_sgldiv( floatx80 a, floatx80 b, float_status *status);
 floatx80 floatx80_cmp( floatx80 a, floatx80 b, float_status *status);
+floatx80 floatx80_tst( floatx80 a, float_status *status );
+floatx80 floatx80_move( floatx80 a, float_status *status);
 
 /*----------------------------------------------------------------------------
 | Software IEC/IEEE extended double-precision operations.