about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-01-22 20:36:31 +0100
committerptitSeb <sebastien.chev@gmail.com>2025-01-22 20:36:31 +0100
commitf235c7f702a4a5873e3b7ef04e3fdf17627e6ca9 (patch)
tree1007152b178e5896812728fc08b09f91f7b97f58 /src
parent8e1e2c78402bf33d17e1e9776083719631acd1c1 (diff)
downloadbox64-f235c7f702a4a5873e3b7ef04e3fdf17627e6ca9.tar.gz
box64-f235c7f702a4a5873e3b7ef04e3fdf17627e6ca9.zip
[INTERPRETER] Improved (V)ADD/MUL/SUB/DIV P(S/D), and improved avx test too
Diffstat (limited to 'src')
-rw-r--r--src/emu/x64run0f.c21
-rw-r--r--src/emu/x64runavx0f.c41
2 files changed, 50 insertions, 12 deletions
diff --git a/src/emu/x64run0f.c b/src/emu/x64run0f.c
index f156b3e2..ef8c0716 100644
--- a/src/emu/x64run0f.c
+++ b/src/emu/x64run0f.c
@@ -47,6 +47,7 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
     reg64_t *oped, *opgd;

     sse_regs_t *opex, *opgx, eax1;

     mmx87_regs_t *opem, *opgm, eam1;

+    uint8_t maskps[4];

 

 #ifdef TEST_INTERPRETER

     x64emu_t *emu = test->emu;

@@ -777,15 +778,21 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
             nextop = F8;

             GETEX(0);

             GETGX;

-            for(int i=0; i<4; ++i)

+            for(int i=0; i<4; ++i) {

+                maskps[i] = isnanf(GX->f[i]) || isnanf(EX->f[i]);

                 GX->f[i] += EX->f[i];

+                if(isnanf(GX->f[i]) && !maskps[i]) GX->ud[i] |= 0x80000000;

+            }

             break;

         case 0x59:                      /* MULPS Gx, Ex */

             nextop = F8;

             GETEX(0);

             GETGX;

-            for(int i=0; i<4; ++i)

+            for(int i=0; i<4; ++i) {

+                maskps[i] = isnanf(GX->f[i]) || isnanf(EX->f[i]);

                 GX->f[i] *= EX->f[i];

+                if(isnanf(GX->f[i]) && !maskps[i]) GX->ud[i] |= 0x80000000;

+            }

             break;

         case 0x5A:                      /* CVTPS2PD Gx, Ex */

             nextop = F8;

@@ -807,8 +814,11 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
             nextop = F8;

             GETEX(0);

             GETGX;

-            for(int i=0; i<4; ++i)

+            for(int i=0; i<4; ++i) {

+                maskps[i] = isnanf(GX->f[i]) || isnanf(EX->f[i]);

                 GX->f[i] -= EX->f[i];

+                if(isnanf(GX->f[i]) && !maskps[i]) GX->ud[i] |= 0x80000000;

+            }

             break;

         case 0x5D:                      /* MINPS Gx, Ex */

             nextop = F8;

@@ -823,8 +833,11 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
             nextop = F8;

             GETEX(0);

             GETGX;

-            for(int i=0; i<4; ++i)

+            for(int i=0; i<4; ++i) {

+                maskps[i] = isnanf(GX->f[i]) || isnanf(EX->f[i]);

                 GX->f[i] /= EX->f[i];

+                if(isnanf(GX->f[i]) && !maskps[i]) GX->ud[i] |= 0x80000000;

+            }

             break;

         case 0x5F:                      /* MAXPS Gx, Ex */

             nextop = F8;

diff --git a/src/emu/x64runavx0f.c b/src/emu/x64runavx0f.c
index 2b3f8189..34cfa742 100644
--- a/src/emu/x64runavx0f.c
+++ b/src/emu/x64runavx0f.c
@@ -52,6 +52,7 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
     reg64_t *oped, *opgd;
     sse_regs_t *opex, *opgx, *opvx, eax1;
     sse_regs_t *opey, *opgy, *opvy, eay1;
+    uint8_t maskps[4];
 
 #ifdef TEST_INTERPRETER
     x64emu_t *emu = test->emu;
@@ -366,13 +367,19 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             GETGX;
             GETVX;
             GETGY;
-            for(int i=0; i<4; ++i)
+            for(int i=0; i<4; ++i) {
+                maskps[i] = isnanf(GX->f[i]) || isnanf(EX->f[i]);
                 GX->f[i] = VX->f[i] + EX->f[i];
+                if(isnanf(GX->f[i]) && !maskps[i]) GX->ud[i] |= 0x80000000;
+            }
             if(vex.l) {
                 GETEY;
                 GETVY;
-                for(int i=0; i<4; ++i)
+                for(int i=0; i<4; ++i) {
+                    maskps[i] = isnanf(GY->f[i]) || isnanf(EY->f[i]);
                     GY->f[i] = VY->f[i] + EY->f[i];
+                    if(isnanf(GY->f[i]) && !maskps[i]) GY->ud[i] |= 0x80000000;
+                }
             } else
                 GY->u128 = 0;
             break;
@@ -382,13 +389,19 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             GETGX;
             GETVX;
             GETGY;
-            for(int i=0; i<4; ++i)
+            for(int i=0; i<4; ++i) {
+                maskps[i] = isnanf(GX->f[i]) || isnanf(EX->f[i]);
                 GX->f[i] = VX->f[i] * EX->f[i];
+                if(isnanf(GX->f[i]) && !maskps[i]) GX->ud[i] |= 0x80000000;
+            }
             if(vex.l) {
                 GETEY;
                 GETVY;
-                for(int i=0; i<4; ++i)
+                for(int i=0; i<4; ++i) {
+                    maskps[i] = isnanf(GY->f[i]) || isnanf(EY->f[i]);
                     GY->f[i] = VY->f[i] * EY->f[i];
+                    if(isnanf(GY->f[i]) && !maskps[i]) GY->ud[i] |= 0x80000000;
+                }
             } else
                 GY->u128 = 0;
             break;
@@ -430,13 +443,19 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             GETGX;
             GETVX;
             GETGY;
-            for(int i=0; i<4; ++i)
+            for(int i=0; i<4; ++i) {
+                maskps[i] = isnanf(GX->f[i]) || isnanf(EX->f[i]);
                 GX->f[i] = VX->f[i] - EX->f[i];
+                if(isnanf(GX->f[i]) && !maskps[i]) GX->ud[i] |= 0x80000000;
+            }
             if(vex.l) {
                 GETEY;
                 GETVY;
-                for(int i=0; i<4; ++i)
+                for(int i=0; i<4; ++i) {
+                    maskps[i] = isnanf(GY->f[i]) || isnanf(EY->f[i]);
                     GY->f[i] = VY->f[i] - EY->f[i];
+                    if(isnanf(GY->f[i]) && !maskps[i]) GY->ud[i] |= 0x80000000;
+                }
             } else
                 GY->u128 = 0;
             break;
@@ -468,13 +487,19 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             GETGX;
             GETVX;
             GETGY;
-            for(int i=0; i<4; ++i)
+            for(int i=0; i<4; ++i) {
+                maskps[i] = isnanf(GX->f[i]) || isnanf(EX->f[i]);
                 GX->f[i] = VX->f[i] / EX->f[i];
+                if(isnanf(GX->f[i]) && !maskps[i]) GX->ud[i] |= 0x80000000;
+            }
             if(vex.l) {
                 GETEY;
                 GETVY;
-                for(int i=0; i<4; ++i)
+                for(int i=0; i<4; ++i) {
+                    maskps[i] = isnanf(GY->f[i]) || isnanf(EY->f[i]);
                     GY->f[i] = VY->f[i] / EY->f[i];
+                    if(isnanf(GY->f[i]) && !maskps[i]) GY->ud[i] |= 0x80000000;
+                }
             } else
                 GY->u128 = 0;
             break;