about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-05-20 14:51:31 +0200
committerptitSeb <sebastien.chev@gmail.com>2025-05-20 14:51:31 +0200
commit72e05a52b2e4700795f46939564ade6d1be55d68 (patch)
tree4fa0985408e696f5f14b749d1434cb9be8c1a3be /src
parente1e3122a1fe834ca12344e0f8a51b995d887b350 (diff)
downloadbox64-72e05a52b2e4700795f46939564ade6d1be55d68.tar.gz
box64-72e05a52b2e4700795f46939564ade6d1be55d68.zip
[INTERP] Fixed D9 F5/F8 (for #2644)
Diffstat (limited to 'src')
-rw-r--r--src/emu/x64rund9.c54
1 files changed, 14 insertions, 40 deletions
diff --git a/src/emu/x64rund9.c b/src/emu/x64rund9.c
index 1f4366f5..0e9bb1b4 100644
--- a/src/emu/x64rund9.c
+++ b/src/emu/x64rund9.c
@@ -168,48 +168,14 @@ uintptr_t RunD9(x64emu_t *emu, rex_t rex, uintptr_t addr, uintptr_t offs)
             }

             break;

 

-        case 0xF8:  /* FPREM */

-            {

-                int e0, e1;

-                frexp(ST0.d, &e0);

-                frexp(ST1.d, &e1);

-                tmp32s = e0 - e1;

-            }

-            if(tmp32s<64)

-            {

-                ll = (int64_t)floor(ST0.d/ST1.d);

-                ST0.d = ST0.d - (ST1.d*ll);

-                emu->sw.f.F87_C2 = 0;

-                emu->sw.f.F87_C1 = (ll&1)?1:0;

-                emu->sw.f.F87_C3 = (ll&2)?1:0;

-                emu->sw.f.F87_C0 = (ll&4)?1:0;

-            } else {

-                ll = (int64_t)(floor((ST0.d/ST1.d))/exp2(tmp32s - 32));

-                ST0.d = ST0.d - ST1.d*ll*exp2(tmp32s - 32);

-                emu->sw.f.F87_C2 = 1;

-            }

-            break;

         case 0xF5:  /* FPREM1 */

             // get exponant(ST(0))-exponant(ST(1)) in temp32s

-            {

-                int e0, e1;

-                frexp(ST0.d, &e0);

-                frexp(ST1.d, &e1);

-                tmp32s = e0 - e1;

-            }

-            if(tmp32s<64)

-            {

-                ll = (int64_t)round(ST0.d/ST1.d);

-                ST0.d = ST0.d - (ST1.d*ll);

-                emu->sw.f.F87_C2 = 0;

-                emu->sw.f.F87_C1 = (ll&1)?1:0;

-                emu->sw.f.F87_C3 = (ll&2)?1:0;

-                emu->sw.f.F87_C0 = (ll&4)?1:0;

-            } else {

-                ll = (int64_t)(trunc((ST0.d/ST1.d))/exp2(tmp32s - 32));

-                ST0.d = ST0.d - ST1.d*ll*exp2(tmp32s - 32);

-                emu->sw.f.F87_C2 = 1;

-            }

+            ll = (int64_t)round(ST0.d/ST1.d);

+            ST0.d = ST0.d - (ST1.d*ll);

+            emu->sw.f.F87_C2 = 0;

+            emu->sw.f.F87_C1 = (ll&1)?1:0;

+            emu->sw.f.F87_C3 = (ll&2)?1:0;

+            emu->sw.f.F87_C0 = (ll&4)?1:0;

             break;

         case 0xF6:  /* FDECSTP */

             emu->top=(emu->top-1)&7;    // this will probably break a few things

@@ -220,6 +186,14 @@ uintptr_t RunD9(x64emu_t *emu, rex_t rex, uintptr_t addr, uintptr_t offs)
             else

                 emu->top=(emu->top+1)&7;    // this will probably break a few things

             break;

+        case 0xF8:  /* FPREM */

+            ll = (int64_t)trunc(ST0.d/ST1.d);

+            ST0.d = ST0.d - (ST1.d*ll);

+            emu->sw.f.F87_C2 = 0;

+            emu->sw.f.F87_C1 = (ll&1)?1:0;

+            emu->sw.f.F87_C3 = (ll&2)?1:0;

+            emu->sw.f.F87_C0 = (ll&4)?1:0;

+            break;

         case 0xF9:  /* FYL2XP1 */

             // Using the log1p instead of log2(ST0+1) can avoid losing precision much,

             // expecially when ST0 is close to zero (which loses the precise when +1).