diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2025-03-26 19:27:19 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2025-03-26 19:27:19 +0100 |
| commit | 9587e490cc94d3df23f59023e826fd6c9c3d5d5c (patch) | |
| tree | 734e79100481a31870a73c41e89ed2d626ede80b /src | |
| parent | ad406383456d906305c213da3b80e24168973915 (diff) | |
| download | box64-9587e490cc94d3df23f59023e826fd6c9c3d5d5c.tar.gz box64-9587e490cc94d3df23f59023e826fd6c9c3d5d5c.zip | |
[INTERP] Fixed Interpreter to have new test30 running
Diffstat (limited to 'src')
| -rw-r--r-- | src/emu/x64runavx660f.c | 8 | ||||
| -rw-r--r-- | src/emu/x64runavxf20f.c | 63 | ||||
| -rw-r--r-- | src/emu/x64runf20f.c | 33 |
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 |