diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-06-05 15:03:44 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-06-05 15:03:44 +0200 |
| commit | dc8e24c7b785874eb6d7cca0df75f0fe6b597ebb (patch) | |
| tree | 508c35c05162f8dc75a819a173f70693755a276f /src | |
| parent | ba411303e951cb51766d42a15be59e2b9d5e67ec (diff) | |
| download | box64-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.c | 56 | ||||
| -rw-r--r-- | src/emu/x64runavx660f.c | 58 | ||||
| -rw-r--r-- | src/emu/x64runavxf20f.c | 28 | ||||
| -rw-r--r-- | src/emu/x64runavxf30f.c | 29 |
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) { |