diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2025-03-26 17:41:44 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2025-03-26 17:41:44 +0100 |
| commit | cb5a52bf40d9f730710edba7f38675317fb58b90 (patch) | |
| tree | 9731998e3d0f1b2a951a2ee94f3889a7705ac503 /src | |
| parent | eaa5f8feec4ed2d8f477753b5fc2ff9e50d1003c (diff) | |
| download | box64-cb5a52bf40d9f730710edba7f38675317fb58b90.tar.gz box64-cb5a52bf40d9f730710edba7f38675317fb58b90.zip | |
[ARM64_DYNAREC] Addedfastnan=0 code to (V)SQRTPS opcodes
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_0f.c | 16 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_avx_0f.c | 18 |
2 files changed, 30 insertions, 4 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c index 89a9af89..eb712db4 100644 --- a/src/dynarec/arm64/dynarec_arm64_0f.c +++ b/src/dynarec/arm64/dynarec_arm64_0f.c @@ -1065,8 +1065,20 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("SQRTPS Gx, Ex"); nextop = F8; GETEX(q0, 0, 0); - GETGX_empty(v0); - VFSQRTQS(v0, q0); + GETGX_empty(q1); + if(!BOX64ENV(dynarec_fastnan)) { + v0 = fpu_get_scratch(dyn, ninst); + v1 = fpu_get_scratch(dyn, ninst); + // check if any input value was NAN + VFCMEQQS(v0, q0, q0); // 0 if NAN, 1 if not NAN + VFSQRTQS(q1, q0); + VFCMEQQS(v1, q1, q1); // 0 => out is NAN + VBICQ(v1, v0, v1); // forget it in any input was a NAN already + VSHLQ_32(v1, v1, 31); // only keep the sign bit + VORRQ(q1, q1, v1); // NAN -> -NAN + } else { + VFSQRTQS(q1, q0); + } break; case 0x52: INST_NAME("RSQRTPS Gx, Ex"); diff --git a/src/dynarec/arm64/dynarec_arm64_avx_0f.c b/src/dynarec/arm64/dynarec_arm64_avx_0f.c index 412def45..b55bfc77 100644 --- a/src/dynarec/arm64/dynarec_arm64_avx_0f.c +++ b/src/dynarec/arm64/dynarec_arm64_avx_0f.c @@ -337,9 +337,23 @@ uintptr_t dynarec64_AVX_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int INST_NAME("VSQRTPS Gx, Ex"); nextop = F8; SKIPTEST(x1); + if(!BOX64ENV(dynarec_fastnan)) { + d0 = fpu_get_scratch(dyn, ninst); + d1 = fpu_get_scratch(dyn, ninst); + } for(int l=0; l<1+vex.l; ++l) { - if(!l) { GETGX_empty_EX(q0, q1, 0); } else { GETGY_empty_EY(q0, q1); } - VFSQRTQS(q0, q1); + if(!l) { GETGX_empty_EX(v0, v1, 0); } else { GETGY_empty_EY(v0, v1); } + if(!BOX64ENV(dynarec_fastnan)) { + // check if any input value was NAN + VFCMEQQS(d0, v1, v1); // 0 if NAN, 1 if not NAN + VFSQRTQS(v0, v1); + VFCMEQQS(d1, v0, v0); // 0 => out is NAN + VBICQ(d1, d0, d1); // forget it in any input was a NAN already + VSHLQ_32(d1, d1, 31); // only keep the sign bit + VORRQ(v0, v0, d1); // NAN -> -NAN + } else { + VFSQRTQS(v0, v1); + } } if(!vex.l) YMM0(gd); break; |