diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-10-23 16:12:41 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-10-23 16:12:41 +0200 |
| commit | 54f8d0510554da4a76d9a1b6b3fc03a950f4d849 (patch) | |
| tree | a19ece5a1f1825537d8e047a335a7ab34871d112 /src | |
| parent | 892f102e4a2c8f0b5381dbe2b35966f655b07209 (diff) | |
| download | box64-54f8d0510554da4a76d9a1b6b3fc03a950f4d849.tar.gz box64-54f8d0510554da4a76d9a1b6b3fc03a950f4d849.zip | |
[ARM64_DYNAREC] Some fixes to x87 opcodes (helps 32bits games on WoW64)
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_d9.c | 14 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_helper.c | 19 |
2 files changed, 25 insertions, 8 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_d9.c b/src/dynarec/arm64/dynarec_arm64_d9.c index 2a95b10a..7b695e02 100644 --- a/src/dynarec/arm64/dynarec_arm64_d9.c +++ b/src/dynarec/arm64/dynarec_arm64_d9.c @@ -195,11 +195,17 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MESSAGE(LOG_DUMP, "Need Optimization\n"); x87_forget(dyn, ninst, x1, x2, 0); CALL(native_ftan, -1); - X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_F); - if(ST_IS_F(0)) { - FMOVS_8(v1, 0b01110000); + if(PK(0)==0xdd && PK(1)==0xd8) { + MESSAGE(LOG_DUMP, "Optimized next DD D8 fstp st0, st0, not emiting 1\n"); + u8 = F8; + u8 = F8; } else { - FMOVD_8(v1, 0b01110000); + X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_F); + if(ST_IS_F(0)) { + FMOVS_8(v1, 0b01110000); + } else { + FMOVD_8(v1, 0b01110000); + } } break; case 0xF3: diff --git a/src/dynarec/arm64/dynarec_arm64_helper.c b/src/dynarec/arm64/dynarec_arm64_helper.c index 0e7e468c..8b334740 100644 --- a/src/dynarec/arm64/dynarec_arm64_helper.c +++ b/src/dynarec/arm64/dynarec_arm64_helper.c @@ -1153,6 +1153,8 @@ int x87_get_current_cache(dynarec_arm_t* dyn, int ninst, int st, int t) #if STEP == 1 if(t==NEON_CACHE_ST_D && (dyn->n.neoncache[dyn->n.x87reg[i]].t==NEON_CACHE_ST_F || dyn->n.neoncache[dyn->n.x87reg[i]].t==NEON_CACHE_ST_I64)) neoncache_promote_double(dyn, ninst, st); + else if(t==NEON_CACHE_ST_I64 && (dyn->n.neoncache[dyn->n.x87reg[i]].t==NEON_CACHE_ST_F)) + neoncache_promote_double(dyn, ninst, st); else if(t==NEON_CACHE_ST_F && (dyn->n.neoncache[dyn->n.x87reg[i]].t==NEON_CACHE_ST_I64)) neoncache_promote_double(dyn, ninst, st); #endif @@ -1258,8 +1260,9 @@ void x87_forget(dynarec_arm_t* dyn, int ninst, int s1, int s2, int st) if(ret==-1) // nothing to do return; MESSAGE(LOG_DUMP, "\tForget x87 Cache for ST%d\n", st); + const int reg = dyn->n.x87reg[ret]; #if STEP == 1 - if(dyn->n.neoncache[dyn->n.x87reg[ret]].t==NEON_CACHE_ST_F || dyn->n.neoncache[dyn->n.x87reg[ret]].t==NEON_CACHE_ST_I64) + if(dyn->n.neoncache[reg].t==NEON_CACHE_ST_F || dyn->n.neoncache[reg].t==NEON_CACHE_ST_I64) neoncache_promote_double(dyn, ninst, st); #endif // prepare offset to fpu => s1 @@ -1271,11 +1274,19 @@ void x87_forget(dynarec_arm_t* dyn, int ninst, int s1, int s2, int st) ADDw_U12(s2, s2, st); ANDw_mask(s2, s2, 0, 2); //mask=7 // (emu->top + i)&7 } - VSTR64_REG_LSL3(dyn->n.x87reg[ret], s1, s2); + if(dyn->n.neoncache[reg].t==NEON_CACHE_ST_F) { + FCVT_D_S(31, reg); + VSTR64_REG_LSL3(31, s1, s2); + } else if(dyn->n.neoncache[reg].t==NEON_CACHE_ST_I64) { + SCVTFDD(31, reg); + VSTR64_REG_LSL3(31, s1, s2); + } else { + VSTR64_REG_LSL3(reg, s1, s2); + } MESSAGE(LOG_DUMP, "\t--------x87 Cache for ST%d\n", st); // and forget that cache - fpu_free_reg(dyn, dyn->n.x87reg[ret]); - dyn->n.neoncache[dyn->n.x87reg[ret]].v = 0; + fpu_free_reg(dyn, reg); + dyn->n.neoncache[reg].v = 0; dyn->n.x87cache[ret] = -1; dyn->n.x87reg[ret] = -1; } |