diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-02-11 11:52:58 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-02-11 11:52:58 +0100 |
| commit | a69e81f0345b5e317e08faa010325c9a01232d09 (patch) | |
| tree | 7e39461036e935382ee051688120d425eab842a3 /src | |
| parent | 5c01fbabac658d7d567efdff333a10bb2be5ca09 (diff) | |
| download | box64-a69e81f0345b5e317e08faa010325c9a01232d09.tar.gz box64-a69e81f0345b5e317e08faa010325c9a01232d09.zip | |
[ARM64_DYNAREC] Improved FFREE/FXAM opcodes (helps 32bits games like SeriousSam2)
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_d9.c | 10 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_dd.c | 11 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_helper.c | 11 |
3 files changed, 29 insertions, 3 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_d9.c b/src/dynarec/arm64/dynarec_arm64_d9.c index c97b2410..f0fa18ac 100644 --- a/src/dynarec/arm64/dynarec_arm64_d9.c +++ b/src/dynarec/arm64/dynarec_arm64_d9.c @@ -160,8 +160,16 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } ANDw_mask(x4, x4, 0, 3); // (emu->top + i)&7 } + // load tag + ADDx_U12(x1, xEmu, offsetof(x64emu_t, p_regs)); + LDRw_REG_LSL2(x3, x1, x2); + CMPSw_U12(x3, 0b11); // empty + MOV32w(x3, 0b100000100000000); + CSELx(x4, x3, x4, cEQ); // empty: C3,C2,C0 = 101 + B_MARK3(cEQ); + // load x2 with ST0 anyway, for sign extraction ADDx_REG_LSL(x1, xEmu, x4, 3); - LDRx_U12(x2, x1, offsetof(x64emu_t, x87)); // load x2 with ST0 anyway, for sign extraction + LDRx_U12(x2, x1, offsetof(x64emu_t, x87)); } else { // simply move from cache reg to x2 v1 = dyn->n.x87reg[i1]; diff --git a/src/dynarec/arm64/dynarec_arm64_dd.c b/src/dynarec/arm64/dynarec_arm64_dd.c index 89221653..42a6f634 100644 --- a/src/dynarec/arm64/dynarec_arm64_dd.c +++ b/src/dynarec/arm64/dynarec_arm64_dd.c @@ -51,10 +51,21 @@ uintptr_t dynarec64_DD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0xC6: case 0xC7: INST_NAME("FFREE STx"); + #if 1 + x87_forget(dyn, ninst, x1, x2, nextop&7); + // empty tags + MOVZw(x3, 0b11); + ADDx_U12(x1, xEmu, offsetof(x64emu_t, p_regs)); + LDRw_U12(x2, xEmu, offsetof(x64emu_t, top)); + ADDw_U12(x2, x2, nextop&7); + ANDw_mask(x2, x2, 0, 2); // mask=7 + STRw_REG_LSL2(x3, x1, x2); + #else MESSAGE(LOG_DUMP, "Need Optimization\n"); x87_purgecache(dyn, ninst, 0, x1, x2, x3); MOV32w(x1, nextop&7); CALL(fpu_do_free, -1); + #endif break; case 0xD0: case 0xD1: diff --git a/src/dynarec/arm64/dynarec_arm64_helper.c b/src/dynarec/arm64/dynarec_arm64_helper.c index cf737369..88008fe8 100644 --- a/src/dynarec/arm64/dynarec_arm64_helper.c +++ b/src/dynarec/arm64/dynarec_arm64_helper.c @@ -1014,7 +1014,13 @@ void x87_do_pop(dynarec_arm_t* dyn, int ninst, int s1) } } } - +static int x87_is_stcached(dynarec_arm_t* dyn, int st) +{ + for (int i=0; i<8; ++i) + if(dyn->n.x87cache[i] == st) + return 1; + return 0; +} void x87_purgecache(dynarec_arm_t* dyn, int ninst, int next, int s1, int s2, int s3) { int ret = 0; @@ -1047,7 +1053,8 @@ void x87_purgecache(dynarec_arm_t* dyn, int ninst, int next, int s1, int s2, int for (int i=0; i<a; ++i) { SUBw_U12(s2, s2, 1); ANDw_mask(s2, s2, 0, 2); //mask=7 // (emu->top + st)&7 - STRw_REG_LSL2(s3, s1, s2); + if(x87_is_stcached(dyn, i)) // to handle ffree + STRw_REG_LSL2(s3, s1, s2); } } else { // empty tags |