diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2025-02-06 18:11:04 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2025-02-06 18:11:04 +0100 |
| commit | 5cfd379e9703266cf4b3778993bc94d0b691fcfc (patch) | |
| tree | 5396673790b93143c12d35a9bcdf177f01e1c5de /src | |
| parent | fecaf3111b88fa6c084317febcadc8b5313156d4 (diff) | |
| download | box64-5cfd379e9703266cf4b3778993bc94d0b691fcfc.tar.gz box64-5cfd379e9703266cf4b3778993bc94d0b691fcfc.zip | |
[ARM64_DYNAREC] Small optims/fixes for a few F2 0F prefixed opcodes
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_f20f.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_f20f.c b/src/dynarec/arm64/dynarec_arm64_f20f.c index d1ff597b..e4a64507 100644 --- a/src/dynarec/arm64/dynarec_arm64_f20f.c +++ b/src/dynarec/arm64/dynarec_arm64_f20f.c @@ -100,11 +100,17 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n GETGX(v0, 1); GETED(0); d1 = fpu_get_scratch(dyn, ninst); + if(BOX64ENV(dynarec_fastround)<2) { + u8 = sse_setround(dyn, ninst, x3, x4, x5); + } if(rex.w) { SCVTFDx(d1, ed); } else { SCVTFDw(d1, ed); } + if(BOX64ENV(dynarec_fastround)<2) { + x87_restoreround(dyn, ninst, u8); + } VMOVeD(v0, 0, d1, 0); break; @@ -206,19 +212,23 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n case 0x51: INST_NAME("SQRTSD Gx, Ex"); nextop = F8; - GETGX(v0, 1); + GETGX(q0, 1); d1 = fpu_get_scratch(dyn, ninst); GETEXSD(d0, 0, 0); if(!BOX64ENV(dynarec_fastnan)) { + v0 = fpu_get_scratch(dyn, ninst); v1 = fpu_get_scratch(dyn, ninst); - FCMLTD_0(v1, d0); - SHL_64(v1, v1, 63); + // check if any input value was NAN + FCMEQD(v0, d0, d0); // 0 if NAN, 1 if not NAN FSQRTD(d1, d0); - VORR(d1, d1, v1); + FCMEQD(v1, d1, d1); // 0 => out is NAN + VBIC(v1, v0, v1); // forget it in any input was a NAN already + SHL_64(v1, v1, 63); // only keep the sign bit + VORR(d1, d1, v1); // NAN -> -NAN } else { FSQRTD(d1, d0); } - VMOVeD(v0, 0, d1, 0); + VMOVeD(q0, 0, d1, 0); break; case 0x58: @@ -271,7 +281,7 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n GETGX(v0, 1); GETEXSD(d0, 0, 0); d1 = fpu_get_scratch(dyn, ninst); - if(BOX64ENV(dynarec_fastround)==2) { + if(BOX64ENV(dynarec_fastround)>1) { FCVT_S_D(d1, d0); } else { u8 = sse_setround(dyn, ninst, x1, x2, x3); |