about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-06-05 15:03:44 +0200
committerptitSeb <sebastien.chev@gmail.com>2024-06-05 15:03:44 +0200
commitdc8e24c7b785874eb6d7cca0df75f0fe6b597ebb (patch)
tree508c35c05162f8dc75a819a173f70693755a276f /src
parentba411303e951cb51766d42a15be59e2b9d5e67ec (diff)
downloadbox64-dc8e24c7b785874eb6d7cca0df75f0fe6b597ebb.tar.gz
box64-dc8e24c7b785874eb6d7cca0df75f0fe6b597ebb.zip
[INTERPRETER] Fixed VCMP opcode familly, that needs more cases on than con-vex CMP familly
Diffstat (limited to 'src')
-rw-r--r--src/emu/x64runavx0f.c56
-rw-r--r--src/emu/x64runavx660f.c58
-rw-r--r--src/emu/x64runavxf20f.c28
-rw-r--r--src/emu/x64runavxf30f.c29
4 files changed, 116 insertions, 55 deletions
diff --git a/src/emu/x64runavx0f.c b/src/emu/x64runavx0f.c
index 3b379e78..58171343 100644
--- a/src/emu/x64runavx0f.c
+++ b/src/emu/x64runavx0f.c
@@ -551,15 +551,25 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             tmp8u = F8;
             for(int i=0; i<4; ++i) {
                 tmp8s = 0;
-                switch(tmp8u&7) {
-                    case 0: tmp8s=(VX->f[i] == EX->f[i]); break;
-                    case 1: tmp8s=isless(VX->f[i], EX->f[i]); break;
-                    case 2: tmp8s=islessequal(VX->f[i], EX->f[i]); break;
-                    case 3: tmp8s=isnan(VX->f[i]) || isnan(EX->f[i]); break;
-                    case 4: tmp8s=(VX->f[i] != EX->f[i]); break;
-                    case 5: tmp8s=isnan(VX->f[i]) || isnan(EX->f[i]) || isgreaterequal(VX->f[i], EX->f[i]); break;
-                    case 6: tmp8s=isnan(VX->f[i]) || isnan(EX->f[i]) || isgreater(VX->f[i], EX->f[i]); break;
-                    case 7: tmp8s=!isnan(VX->f[i]) && !isnan(EX->f[i]); break;
+                int is_nan = isnan(VX->f[i]) || isnan(EX->f[i]);
+                // the 1f..0f opcode are singaling/unsignaling, wich is not handled
+                switch(tmp8u&0x0f) {
+                    case 0x00: tmp8s=(VX->f[i] == EX->f[i]) && !is_nan; break;
+                    case 0x01: tmp8s=isless(VX->f[i], EX->f[i]) && !is_nan; break;
+                    case 0x02: tmp8s=islessequal(VX->f[i], EX->f[i]) && !is_nan; break;
+                    case 0x03: tmp8s=is_nan; break;
+                    case 0x04: tmp8s=(VX->f[i] != EX->f[i]) || is_nan; break;
+                    case 0x05: tmp8s=is_nan || isgreaterequal(VX->f[i], EX->f[i]); break;
+                    case 0x06: tmp8s=is_nan || isgreater(VX->f[i], EX->f[i]); break;
+                    case 0x07: tmp8s=!is_nan; break;
+                    case 0x08: tmp8s=(VX->f[i] == EX->f[i]) || is_nan; break;
+                    case 0x09: tmp8s=isless(VX->f[i], EX->f[i]) || is_nan; break;
+                    case 0x0a: tmp8s=islessequal(VX->f[i], EX->f[i]) || is_nan; break;
+                    case 0x0b: tmp8s=0; break;
+                    case 0x0c: tmp8s=(VX->f[i] != EX->f[i]) && !is_nan; break;
+                    case 0x0d: tmp8s=isgreaterequal(VX->f[i], EX->f[i]) && !is_nan; break;
+                    case 0x0e: tmp8s=isgreater(VX->f[i], EX->f[i]) && !is_nan; break;
+                    case 0x0f: tmp8s=1; break;
                 }
                 GX->ud[i]=(tmp8s)?0xffffffff:0;
             }
@@ -568,15 +578,25 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
                 GETVY;
                 for(int i=0; i<4; ++i) {
                     tmp8s = 0;
-                    switch(tmp8u&7) {
-                        case 0: tmp8s=(VY->f[i] == EY->f[i]); break;
-                        case 1: tmp8s=isless(VY->f[i], EY->f[i]); break;
-                        case 2: tmp8s=islessequal(VY->f[i], EY->f[i]); break;
-                        case 3: tmp8s=isnan(VY->f[i]) || isnan(EY->f[i]); break;
-                        case 4: tmp8s=(VY->f[i] != EY->f[i]); break;
-                        case 5: tmp8s=isnan(VY->f[i]) || isnan(EY->f[i]) || isgreaterequal(VY->f[i], EY->f[i]); break;
-                        case 6: tmp8s=isnan(VY->f[i]) || isnan(EY->f[i]) || isgreater(VY->f[i], EY->f[i]); break;
-                        case 7: tmp8s=!isnan(VY->f[i]) && !isnan(EY->f[i]); break;
+                    int is_nan = isnan(VY->f[i]) || isnan(EY->f[i]);
+                    // the 1f..0f opcode are singaling/unsignaling, wich is not handled
+                    switch(tmp8u&0x0f) {
+                        case 0x00: tmp8s=(VY->f[i] == EY->f[i]) && !is_nan; break;
+                        case 0x01: tmp8s=isless(VY->f[i], EY->f[i]) && !is_nan; break;
+                        case 0x02: tmp8s=islessequal(VY->f[i], EY->f[i]) && !is_nan; break;
+                        case 0x03: tmp8s=is_nan; break;
+                        case 0x04: tmp8s=(VY->f[i] != EY->f[i]) || is_nan; break;
+                        case 0x05: tmp8s=is_nan || isgreaterequal(VY->f[i], EY->f[i]); break;
+                        case 0x06: tmp8s=is_nan || isgreater(VY->f[i], EY->f[i]); break;
+                        case 0x07: tmp8s=!is_nan; break;
+                        case 0x08: tmp8s=(VY->f[i] == EY->f[i]) || is_nan; break;
+                        case 0x09: tmp8s=isless(VY->f[i], EY->f[i]) || is_nan; break;
+                        case 0x0a: tmp8s=islessequal(VY->f[i], EY->f[i]) || is_nan; break;
+                        case 0x0b: tmp8s=0; break;
+                        case 0x0c: tmp8s=(VY->f[i] != EY->f[i]) && !is_nan; break;
+                        case 0x0d: tmp8s=isgreaterequal(VY->f[i], EY->f[i]) && !is_nan; break;
+                        case 0x0e: tmp8s=isgreater(VY->f[i], EY->f[i]) && !is_nan; break;
+                        case 0x0f: tmp8s=1; break;
                     }
                     GY->ud[i]=(tmp8s)?0xffffffff:0;
                 }
diff --git a/src/emu/x64runavx660f.c b/src/emu/x64runavx660f.c
index 14552eaa..ba09a4dd 100644
--- a/src/emu/x64runavx660f.c
+++ b/src/emu/x64runavx660f.c
@@ -1238,7 +1238,7 @@ uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             } // no upper raz?
             break;
 
-        case 0xC2:                      /* CMPPD Gx, Vx, Ex, Ib */
+        case 0xC2:                      /* VCMPPD Gx, Vx, Ex, Ib */
             nextop = F8;
             GETEX(1);
             GETGX;
@@ -1247,15 +1247,25 @@ uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             tmp8u = F8;
             for(int i=0; i<2; ++i) {
                 tmp8s = 0;
-                switch(tmp8u&7) {
-                    case 0: tmp8s=(VX->d[i] == EX->d[i]); break;
-                    case 1: tmp8s=isless(VX->d[i], EX->d[i]); break;
-                    case 2: tmp8s=islessequal(VX->d[i], EX->d[i]); break;
-                    case 3: tmp8s=isnan(VX->d[i]) || isnan(EX->d[i]); break;
-                    case 4: tmp8s=isnan(VX->d[i]) || isnan(EX->d[i]) || (VX->d[i] != EX->d[i]); break;
-                    case 5: tmp8s=isnan(VX->d[i]) || isnan(EX->d[i]) || isgreaterequal(VX->d[i], EX->d[i]); break;
-                    case 6: tmp8s=isnan(VX->d[i]) || isnan(EX->d[i]) || isgreater(VX->d[i], EX->d[i]); break;
-                    case 7: tmp8s=!isnan(VX->d[i]) && !isnan(EX->d[i]); break;
+                int is_nan = isnan(VX->d[i]) || isnan(EX->d[i]);
+                // the 1f..0f opcode are singaling/unsignaling, wich is not handled
+                switch(tmp8u&0x0f) {
+                    case 0x00: tmp8s=(VX->d[i] == EX->d[i]) && !is_nan; break;
+                    case 0x01: tmp8s=isless(VX->d[i], EX->d[i]) && !is_nan; break;
+                    case 0x02: tmp8s=islessequal(VX->d[i], EX->d[i]) && !is_nan; break;
+                    case 0x03: tmp8s=is_nan; break;
+                    case 0x04: tmp8s=(VX->d[i] != EX->d[i]) || is_nan; break;
+                    case 0x05: tmp8s=is_nan || isgreaterequal(VX->d[i], EX->d[i]); break;
+                    case 0x06: tmp8s=is_nan || isgreater(VX->d[i], EX->d[i]); break;
+                    case 0x07: tmp8s=!is_nan; break;
+                    case 0x08: tmp8s=(VX->d[i] == EX->d[i]) || is_nan; break;
+                    case 0x09: tmp8s=isless(VX->d[i], EX->d[i]) || is_nan; break;
+                    case 0x0a: tmp8s=islessequal(VX->d[i], EX->d[i]) || is_nan; break;
+                    case 0x0b: tmp8s=0; break;
+                    case 0x0c: tmp8s=(VX->d[i] != EX->d[i]) && !is_nan; break;
+                    case 0x0d: tmp8s=isgreaterequal(VX->d[i], EX->d[i]) && !is_nan; break;
+                    case 0x0e: tmp8s=isgreater(VX->d[i], EX->d[i]) && !is_nan; break;
+                    case 0x0f: tmp8s=1; break;
                 }
                 GX->q[i]=(tmp8s)?0xffffffffffffffffLL:0LL;
             }
@@ -1264,15 +1274,25 @@ uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
                 GETVY;
                 for(int i=0; i<2; ++i) {
                     tmp8s = 0;
-                    switch(tmp8u&7) {
-                        case 0: tmp8s=(VY->d[i] == EY->d[i]); break;
-                        case 1: tmp8s=isless(VY->d[i], EY->d[i]); break;
-                        case 2: tmp8s=islessequal(VY->d[i], EY->d[i]); break;
-                        case 3: tmp8s=isnan(VY->d[i]) || isnan(EY->d[i]); break;
-                        case 4: tmp8s=isnan(VY->d[i]) || isnan(EY->d[i]) || (VY->d[i] != EY->d[i]); break;
-                        case 5: tmp8s=isnan(VY->d[i]) || isnan(EY->d[i]) || isgreaterequal(VY->d[i], EY->d[i]); break;
-                        case 6: tmp8s=isnan(VY->d[i]) || isnan(EY->d[i]) || isgreater(VY->d[i], EY->d[i]); break;
-                        case 7: tmp8s=!isnan(VY->d[i]) && !isnan(EY->d[i]); break;
+                    int is_nan = isnan(VY->d[i]) || isnan(EY->d[i]);
+                    // the 1f..0f opcode are singaling/unsignaling, wich is not handled
+                    switch(tmp8u&0x0f) {
+                        case 0x00: tmp8s=(VY->d[i] == EY->d[i]) && !is_nan; break;
+                        case 0x01: tmp8s=isless(VY->d[i], EY->d[i]) && !is_nan; break;
+                        case 0x02: tmp8s=islessequal(VY->d[i], EY->d[i]) && !is_nan; break;
+                        case 0x03: tmp8s=is_nan; break;
+                        case 0x04: tmp8s=(VY->d[i] != EY->d[i]) || is_nan; break;
+                        case 0x05: tmp8s=is_nan || isgreaterequal(VY->d[i], EY->d[i]); break;
+                        case 0x06: tmp8s=is_nan || isgreater(VY->d[i], EY->d[i]); break;
+                        case 0x07: tmp8s=!is_nan; break;
+                        case 0x08: tmp8s=(VY->d[i] == EY->d[i]) || is_nan; break;
+                        case 0x09: tmp8s=isless(VY->d[i], EY->d[i]) || is_nan; break;
+                        case 0x0a: tmp8s=islessequal(VY->d[i], EY->d[i]) || is_nan; break;
+                        case 0x0b: tmp8s=0; break;
+                        case 0x0c: tmp8s=(VY->d[i] != EY->d[i]) && !is_nan; break;
+                        case 0x0d: tmp8s=isgreaterequal(VY->d[i], EY->d[i]) && !is_nan; break;
+                        case 0x0e: tmp8s=isgreater(VY->d[i], EY->d[i]) && !is_nan; break;
+                        case 0x0f: tmp8s=1; break;
                     }
                     GY->q[i]=(tmp8s)?0xffffffffffffffffLL:0LL;
                 }
diff --git a/src/emu/x64runavxf20f.c b/src/emu/x64runavxf20f.c
index b607fc27..a6224f59 100644
--- a/src/emu/x64runavxf20f.c
+++ b/src/emu/x64runavxf20f.c
@@ -407,15 +407,25 @@ uintptr_t RunAVX_F20F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             GETGY;
             tmp8u = F8;
             tmp8s = 0;
-            switch(tmp8u&7) {
-                case 0: tmp8s=(VX->d[0] == EX->d[0]); break;
-                case 1: tmp8s=isless(VX->d[0], EX->d[0]) && !(isnan(VX->d[0]) || isnan(EX->d[0])); break;
-                case 2: tmp8s=islessequal(VX->d[0], EX->d[0]) && !(isnan(VX->d[0]) || isnan(EX->d[0])); break;
-                case 3: tmp8s=isnan(VX->d[0]) || isnan(EX->d[0]); break;
-                case 4: tmp8s=isnan(VX->d[0]) || isnan(EX->d[0]) || (VX->d[0] != EX->d[0]); break;
-                case 5: tmp8s=isnan(VX->d[0]) || isnan(EX->d[0]) || isgreaterequal(VX->d[0], EX->d[0]); break;
-                case 6: tmp8s=isnan(VX->d[0]) || isnan(EX->d[0]) || isgreater(VX->d[0], EX->d[0]); break;
-                case 7: tmp8s=!isnan(VX->d[0]) && !isnan(EX->d[0]); break;
+            int is_nan = isnan(VX->d[0]) || isnan(EX->d[0]);
+            // the 1f..0f opcode are singaling/unsignaling, wich is not handled
+            switch(tmp8u&0x0f) {
+                case 0x00: tmp8s=(VX->d[0] == EX->d[0]) && !is_nan; break;
+                case 0x01: tmp8s=isless(VX->d[0], EX->d[0]) && !is_nan; break;
+                case 0x02: tmp8s=islessequal(VX->d[0], EX->d[0]) && !is_nan; break;
+                case 0x03: tmp8s=is_nan; break;
+                case 0x04: tmp8s=(VX->d[0] != EX->d[0]) || is_nan; break;
+                case 0x05: tmp8s=is_nan || isgreaterequal(VX->d[0], EX->d[0]); break;
+                case 0x06: tmp8s=is_nan || isgreater(VX->d[0], EX->d[0]); break;
+                case 0x07: tmp8s=!is_nan; break;
+                case 0x08: tmp8s=(VX->d[0] == EX->d[0]) || is_nan; break;
+                case 0x09: tmp8s=isless(VX->d[0], EX->d[0]) || is_nan; break;
+                case 0x0a: tmp8s=islessequal(VX->d[0], EX->d[0]) || is_nan; break;
+                case 0x0b: tmp8s=0; break;
+                case 0x0c: tmp8s=(VX->d[0] != EX->d[0]) && !is_nan; break;
+                case 0x0d: tmp8s=isgreaterequal(VX->d[0], EX->d[0]) && !is_nan; break;
+                case 0x0e: tmp8s=isgreater(VX->d[0], EX->d[0]) && !is_nan; break;
+                case 0x0f: tmp8s=1; break;
             }
             GX->q[0]=(tmp8s)?0xffffffffffffffffLL:0LL;
             GX->q[1] = VX->q[1];
diff --git a/src/emu/x64runavxf30f.c b/src/emu/x64runavxf30f.c
index dda2b0f6..89c0bad4 100644
--- a/src/emu/x64runavxf30f.c
+++ b/src/emu/x64runavxf30f.c
@@ -52,6 +52,7 @@ uintptr_t RunAVX_F30F(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;
+    int is_nan;
 
 
 #ifdef TEST_INTERPRETER
@@ -448,15 +449,25 @@ uintptr_t RunAVX_F30F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             GETGY;
             tmp8u = F8;
             tmp8s = 0;
-            switch(tmp8u&7) {
-                case 0: tmp8s=(VX->f[0] == EX->f[0]); break;
-                case 1: tmp8s=isless(VX->f[0], EX->f[0]) && !(isnan(VX->f[0]) || isnan(EX->f[0])); break;
-                case 2: tmp8s=islessequal(VX->f[0], EX->f[0]) && !(isnan(VX->f[0]) || isnan(EX->f[0])); break;
-                case 3: tmp8s=isnan(VX->f[0]) || isnan(EX->f[0]); break;
-                case 4: tmp8s=isnan(VX->f[0]) || isnan(EX->f[0]) || (VX->f[0] != EX->f[0]); break;
-                case 5: tmp8s=isnan(VX->f[0]) || isnan(EX->f[0]) || isgreaterequal(VX->f[0], EX->f[0]); break;
-                case 6: tmp8s=isnan(VX->f[0]) || isnan(EX->f[0]) || isgreater(VX->f[0], EX->f[0]); break;
-                case 7: tmp8s=!isnan(VX->f[0]) && !isnan(EX->f[0]); break;
+            is_nan = isnan(VX->f[0]) || isnan(EX->f[0]);
+            // the 1f..0f opcode are singaling/unsignaling, wich is not handled
+            switch(tmp8u&0x0f) {
+                case 0x00: tmp8s=(VX->f[0] == EX->f[0]) && !is_nan; break;
+                case 0x01: tmp8s=isless(VX->f[0], EX->f[0]) && !is_nan; break;
+                case 0x02: tmp8s=islessequal(VX->f[0], EX->f[0]) && !is_nan; break;
+                case 0x03: tmp8s=is_nan; break;
+                case 0x04: tmp8s=(VX->f[0] != EX->f[0]) || is_nan; break;
+                case 0x05: tmp8s=is_nan || isgreaterequal(VX->f[0], EX->f[0]); break;
+                case 0x06: tmp8s=is_nan || isgreater(VX->f[0], EX->f[0]); break;
+                case 0x07: tmp8s=!is_nan; break;
+                case 0x08: tmp8s=(VX->f[0] == EX->f[0]) || is_nan; break;
+                case 0x09: tmp8s=isless(VX->f[0], EX->f[0]) || is_nan; break;
+                case 0x0a: tmp8s=islessequal(VX->f[0], EX->f[0]) || is_nan; break;
+                case 0x0b: tmp8s=0; break;
+                case 0x0c: tmp8s=(VX->f[0] != EX->f[0]) && !is_nan; break;
+                case 0x0d: tmp8s=isgreaterequal(VX->f[0], EX->f[0]) && !is_nan; break;
+                case 0x0e: tmp8s=isgreater(VX->f[0], EX->f[0]) && !is_nan; break;
+                case 0x0f: tmp8s=1; break;
             }
             GX->ud[0]=(tmp8s)?0xffffffff:0;
             if(GX!=VX) {