about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-03-26 19:27:19 +0100
committerptitSeb <sebastien.chev@gmail.com>2025-03-26 19:27:19 +0100
commit9587e490cc94d3df23f59023e826fd6c9c3d5d5c (patch)
tree734e79100481a31870a73c41e89ed2d626ede80b /src
parentad406383456d906305c213da3b80e24168973915 (diff)
downloadbox64-9587e490cc94d3df23f59023e826fd6c9c3d5d5c.tar.gz
box64-9587e490cc94d3df23f59023e826fd6c9c3d5d5c.zip
[INTERP] Fixed Interpreter to have new test30 running
Diffstat (limited to 'src')
-rw-r--r--src/emu/x64runavx660f.c8
-rw-r--r--src/emu/x64runavxf20f.c63
-rw-r--r--src/emu/x64runf20f.c33
3 files changed, 100 insertions, 4 deletions
diff --git a/src/emu/x64runavx660f.c b/src/emu/x64runavx660f.c
index f0e39120..45aaf043 100644
--- a/src/emu/x64runavx660f.c
+++ b/src/emu/x64runavx660f.c
@@ -453,7 +453,7 @@ uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             GETVX;
             GETGY;
             for(int i=0; i<2; ++i)
-                if (isnan(VX->d[i]) || isnan(EX->d[i]) || isgreater(VX->d[i], EX->d[i]))
+                if (isnan(VX->d[i]) || isnan(EX->d[i]) || !isgreater(EX->d[i], VX->d[i]))
                     GX->d[i] = EX->d[i];
                 else
                     GX->d[i] = VX->d[i];
@@ -461,7 +461,7 @@ uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
                 GETEY;
                 GETVY;
                 for(int i=0; i<2; ++i)
-                    if (isnan(VY->d[i]) || isnan(EY->d[i]) || isgreater(VY->d[i], EY->d[i]))
+                    if (isnan(VY->d[i]) || isnan(EY->d[i]) || !isgreater(EY->d[i], VY->d[i]))
                         GY->d[i] = EY->d[i];
                     else
                         GY->d[i] = VY->d[i];
@@ -507,7 +507,7 @@ uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             GETVX;
             GETGY;
             for(int i=0; i<2; ++i)
-                if (isnan(VX->d[i]) || isnan(EX->d[i]) || isgreater(EX->d[i], VX->d[i]))
+                if (isnan(VX->d[i]) || isnan(EX->d[i]) || !isgreater(VX->d[i], EX->d[i]))
                     GX->d[i] = EX->d[i];
                 else
                     GX->d[i] = VX->d[i];
@@ -515,7 +515,7 @@ uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
                 GETEY;
                 GETVY;
                 for(int i=0; i<2; ++i)
-                    if (isnan(VY->d[i]) || isnan(EY->d[i]) || isgreater(EY->d[i], VY->d[i]))
+                    if (isnan(VY->d[i]) || isnan(EY->d[i]) || !isgreater(VY->d[i], EY->d[i]))
                         GY->d[i] = EY->d[i];
                     else
                         GY->d[i] = VY->d[i];
diff --git a/src/emu/x64runavxf20f.c b/src/emu/x64runavxf20f.c
index 37bc57f6..34280a00 100644
--- a/src/emu/x64runavxf20f.c
+++ b/src/emu/x64runavxf20f.c
@@ -49,6 +49,9 @@ uintptr_t RunAVX_F20F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
     sse_regs_t *opex, *opgx, *opvx, eax1;
     sse_regs_t *opey, *opgy, *opvy, eay1;
     int is_nan;
+    #ifndef NOALIGN
+    int nan_mask[4];
+    #endif
 
 
 #ifdef TEST_INTERPRETER
@@ -333,30 +336,62 @@ uintptr_t RunAVX_F20F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
                 eax1 = *EX;
                 EX = &eax1;
             }
+            #ifndef NOALIGN
+            nan_mask[0] = isnanf(VX->f[0]) || isnanf(VX->f[1]);
+            nan_mask[1] = isnanf(VX->f[2]) || isnanf(VX->f[3]);
+            #endif
             GX->f[0] = VX->f[0] + VX->f[1];
             GX->f[1] = VX->f[2] + VX->f[3];
             if(EX==VX) {
                 GX->f[2] = GX->f[0];
                 GX->f[3] = GX->f[1];
+                #ifndef NOALIGN
+                nan_mask[2] = nan_mask[0];
+                nan_mask[3] = nan_mask[1];
+                #endif
             } else {
+                #ifndef NOALIGN
+                nan_mask[2] = isnanf(EX->f[0]) || isnanf(EX->f[1]);
+                nan_mask[3] = isnanf(EX->f[2]) || isnanf(EX->f[3]);
+                #endif
                 GX->f[2] = EX->f[0] + EX->f[1];
                 GX->f[3] = EX->f[2] + EX->f[3];
             }
+            #ifndef NOALIGN
+            for(int i=0; i<4; ++i)
+                if(!nan_mask[i] && isnanf(GX->f[i])) GX->ud[i] |= 0x80000000;
+            #endif
             if(vex.l) {
                 if(GY==EY) {
                     eay1 = *EY;
                     EY = &eay1;
                 }
                 GETVY;
+                #ifndef NOALIGN
+                nan_mask[0] = isnanf(VY->f[0]) || isnanf(VY->f[1]);
+                nan_mask[1] = isnanf(VY->f[2]) || isnanf(VY->f[3]);
+                #endif
                 GY->f[0] = VY->f[0] + VY->f[1];
                 GY->f[1] = VY->f[2] + VY->f[3];
                 if(EY==VY) {
                     GY->f[2] = GY->f[0];
                     GY->f[3] = GY->f[1];
+                    #ifndef NOALIGN
+                    nan_mask[2] = nan_mask[0];
+                    nan_mask[3] = nan_mask[1];
+                    #endif
                 } else {
+                    #ifndef NOALIGN
+                    nan_mask[2] = isnanf(EY->f[0]) || isnanf(EY->f[1]);
+                    nan_mask[3] = isnanf(EY->f[2]) || isnanf(EY->f[3]);
+                    #endif
                     GY->f[2] = EY->f[0] + EY->f[1];
                     GY->f[3] = EY->f[2] + EY->f[3];
                 }
+                #ifndef NOALIGN
+                for(int i=0; i<4; ++i)
+                    if(!nan_mask[i] && isnanf(GY->f[i])) GY->ud[i] |= 0x80000000;
+                #endif
             } else
                 GY->u128 = 0;
             break;
@@ -371,12 +406,24 @@ uintptr_t RunAVX_F20F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
                 eax1 = *EX;
                 EX = &eax1;
             }
+            #ifndef NOALIGN
+            nan_mask[0] = isnanf(VX->f[0]) || isnanf(VX->f[1]);
+            nan_mask[1] = isnanf(VX->f[2]) || isnanf(VX->f[3]);
+            #endif
             GX->f[0] = VX->f[0] - VX->f[1];
             GX->f[1] = VX->f[2] - VX->f[3];
             if(EX==VX) {
                 GX->f[2] = GX->f[0];
                 GX->f[3] = GX->f[1];
+                #ifndef NOALIGN
+                nan_mask[2] = nan_mask[0];
+                nan_mask[3] = nan_mask[1];
+                #endif
             } else {
+                #ifndef NOALIGN
+                nan_mask[2] = isnanf(EX->f[0]) || isnanf(EX->f[1]);
+                nan_mask[3] = isnanf(EX->f[2]) || isnanf(EX->f[3]);
+                #endif
                 GX->f[2] = EX->f[0] - EX->f[1];
                 GX->f[3] = EX->f[2] - EX->f[3];
             }
@@ -386,15 +433,31 @@ uintptr_t RunAVX_F20F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
                     EY = &eay1;
                 }
                 GETVY;
+                #ifndef NOALIGN
+                nan_mask[0] = isnanf(VY->f[0]) || isnanf(VY->f[1]);
+                nan_mask[1] = isnanf(VY->f[2]) || isnanf(VY->f[3]);
+                #endif
                 GY->f[0] = VY->f[0] - VY->f[1];
                 GY->f[1] = VY->f[2] - VY->f[3];
                 if(EY==VY) {
                     GY->f[2] = GY->f[0];
                     GY->f[3] = GY->f[1];
+                    #ifndef NOALIGN
+                    nan_mask[2] = nan_mask[0];
+                    nan_mask[3] = nan_mask[1];
+                    #endif
                 } else {
+                    #ifndef NOALIGN
+                    nan_mask[2] = isnanf(EY->f[0]) || isnanf(EY->f[1]);
+                    nan_mask[3] = isnanf(EY->f[2]) || isnanf(EY->f[3]);
+                    #endif
                     GY->f[2] = EY->f[0] - EY->f[1];
                     GY->f[3] = EY->f[2] - EY->f[3];
                 }
+                #ifndef NOALIGN
+                for(int i=0; i<4; ++i)
+                    if(!nan_mask[i] && isnanf(GY->f[i])) GY->ud[i] |= 0x80000000;
+                #endif
             } else
                 GY->u128 = 0;
             break;
diff --git a/src/emu/x64runf20f.c b/src/emu/x64runf20f.c
index aa2d2fa0..a247a9f0 100644
--- a/src/emu/x64runf20f.c
+++ b/src/emu/x64runf20f.c
@@ -41,6 +41,7 @@ uintptr_t RunF20F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
     sse_regs_t *opex, *opgx, eax1;

     mmx87_regs_t *opgm;

     #ifndef NOALIGN

+    int nan_mask[4];

     int is_nan;

     #endif

     #ifdef TEST_INTERPRETER

@@ -351,27 +352,59 @@ uintptr_t RunF20F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
         nextop = F8;

         _GETEX(0);

         GETGX;

+        #ifndef NOALIGN

+        nan_mask[0] = isnanf(GX->f[0]) || isnanf(GX->f[1]);

+        nan_mask[1] = isnanf(GX->f[2]) || isnanf(GX->f[3]);

+        #endif

         GX->f[0] += GX->f[1];

         GX->f[1] = GX->f[2] + GX->f[3];

         if(EX==GX) {

             GX->q[1] = GX->q[0];

+            #ifndef NOALIGN

+            nan_mask[2] = nan_mask[0];

+            nan_mask[3] = nan_mask[1];

+            #endif

         } else {

+            #ifndef NOALIGN

+            nan_mask[2] = isnanf(EX->f[0]) || isnanf(EX->f[1]);

+            nan_mask[3] = isnanf(EX->f[2]) || isnanf(EX->f[3]);

+            #endif

             GX->f[2] = EX->f[0] + EX->f[1];

             GX->f[3] = EX->f[2] + EX->f[3];

         }

+        #ifndef NOALIGN

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

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

+        #endif

         break;

     case 0x7D:  /* HSUBPS Gx, Ex */

         nextop = F8;

         _GETEX(0);

         GETGX;

+        #ifndef NOALIGN

+        nan_mask[0] = isnanf(GX->f[0]) || isnanf(GX->f[1]);

+        nan_mask[1] = isnanf(GX->f[2]) || isnanf(GX->f[3]);

+        #endif

         GX->f[0] -= GX->f[1];

         GX->f[1] = GX->f[2] - GX->f[3];

         if(EX==GX) {

             GX->q[1] = GX->q[0];

+            #ifndef NOALIGN

+            nan_mask[2] = nan_mask[0];

+            nan_mask[3] = nan_mask[1];

+            #endif

         } else {

+            #ifndef NOALIGN

+            nan_mask[2] = isnanf(EX->f[0]) || isnanf(EX->f[1]);

+            nan_mask[3] = isnanf(EX->f[2]) || isnanf(EX->f[3]);

+            #endif

             GX->f[2] = EX->f[0] - EX->f[1];

             GX->f[3] = EX->f[2] - EX->f[3];

         }

+        #ifndef NOALIGN

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

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

+        #endif

         break;

 

     GOCOND(0x80