diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2025-01-22 20:36:31 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2025-01-22 20:36:31 +0100 |
| commit | f235c7f702a4a5873e3b7ef04e3fdf17627e6ca9 (patch) | |
| tree | 1007152b178e5896812728fc08b09f91f7b97f58 /src | |
| parent | 8e1e2c78402bf33d17e1e9776083719631acd1c1 (diff) | |
| download | box64-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.c | 21 | ||||
| -rw-r--r-- | src/emu/x64runavx0f.c | 41 |
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; |