diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-03-30 14:00:27 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-03-30 14:00:27 +0200 |
| commit | d93e53498d18cbabb601a4fffb5224925aa5db24 (patch) | |
| tree | 83a51f24a30a803f73aeead314011b292c2e190b /src | |
| parent | e82d5264144baa0236d751c63d8700c78eea0b46 (diff) | |
| download | box64-d93e53498d18cbabb601a4fffb5224925aa5db24.tar.gz box64-d93e53498d18cbabb601a4fffb5224925aa5db24.zip | |
[DYNAREC] Fixed handling of x87 top and stack on TEST_INTERPRETER
Diffstat (limited to 'src')
| -rwxr-xr-x | src/dynarec/arm64/dynarec_arm64_helper.c | 57 | ||||
| -rwxr-xr-x | src/dynarec/arm64/dynarec_arm64_helper.h | 2 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_native_pass.c | 2 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.c | 41 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 2 |
5 files changed, 100 insertions, 4 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.c b/src/dynarec/arm64/dynarec_arm64_helper.c index 1f897344..cbbf0c38 100755 --- a/src/dynarec/arm64/dynarec_arm64_helper.c +++ b/src/dynarec/arm64/dynarec_arm64_helper.c @@ -906,7 +906,27 @@ void x87_purgecache(dynarec_arm_t* dyn, int ninst, int next, int s1, int s2, int static void x87_reflectcache(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3) { - x87_stackcount(dyn, ninst, s1); + // Synch top & stack counter + int a = dyn->n.x87stack; + if(a) { + // Add x87stack to emu fpu_stack + LDRw_U12(s2, xEmu, offsetof(x64emu_t, fpu_stack)); + if(a>0) { + ADDw_U12(s2, s2, a); + } else { + SUBw_U12(s2, s2, -a); + } + STRw_U12(s2, xEmu, offsetof(x64emu_t, fpu_stack)); + // Sub x87stack to top, with and 7 + LDRw_U12(s2, xEmu, offsetof(x64emu_t, top)); + if(a>0) { + SUBw_U12(s2, s2, a); + } else { + ADDw_U12(s2, s2, -a); + } + ANDw_mask(s2, s2, 0, 2); //mask=7 + STRw_U12(s2, xEmu, offsetof(x64emu_t, top)); + } int ret = 0; for (int i=0; (i<8) && (!ret); ++i) if(dyn->n.x87cache[i] != -1) @@ -916,7 +936,9 @@ static void x87_reflectcache(dynarec_arm_t* dyn, int ninst, int s1, int s2, int // prepare offset to fpu => s1 ADDx_U12(s1, xEmu, offsetof(x64emu_t, x87)); // Get top - LDRw_U12(s2, xEmu, offsetof(x64emu_t, top)); + if(!a) { + LDRw_U12(s2, xEmu, offsetof(x64emu_t, top)); + } // loop all cache entries for (int i=0; i<8; ++i) if(dyn->n.x87cache[i]!=-1) { @@ -926,6 +948,31 @@ static void x87_reflectcache(dynarec_arm_t* dyn, int ninst, int s1, int s2, int } } +static void x87_unreflectcache(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3) +{ + // go back with the top & stack counter + int a = dyn->n.x87stack; + if(a) { + // Sub x87stack to emu fpu_stack + LDRw_U12(s2, xEmu, offsetof(x64emu_t, fpu_stack)); + if(a>0) { + SUBw_U12(s2, s2, a); + } else { + ADDw_U12(s2, s2, -a); + } + STRw_U12(s2, xEmu, offsetof(x64emu_t, fpu_stack)); + // Add x87stack to top, with and 7 + LDRw_U12(s2, xEmu, offsetof(x64emu_t, top)); + if(a>0) { + ADDw_U12(s2, s2, a); + } else { + SUBw_U12(s2, s2, -a); + } + ANDw_mask(s2, s2, 0, 2); //mask=7 + STRw_U12(s2, xEmu, offsetof(x64emu_t, top)); + } +} + int x87_get_current_cache(dynarec_arm_t* dyn, int ninst, int st, int t) { // search in cache first @@ -1753,6 +1800,12 @@ void fpu_reflectcache(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3) sse_reflectcache(dyn, ninst, s1); } +void fpu_unreflectcache(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3) +{ + // need to undo some things on the x87 tracking + x87_unreflectcache(dyn, ninst, s1, s2, s3); +} + void fpu_reset(dynarec_arm_t* dyn) { x87_reset(dyn); diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h index 64f05583..5c908685 100755 --- a/src/dynarec/arm64/dynarec_arm64_helper.h +++ b/src/dynarec/arm64/dynarec_arm64_helper.h @@ -979,6 +979,7 @@ void* arm64_next(x64emu_t* emu, uintptr_t addr); #define mmx_purgecache STEPNAME(mmx_purgecache) #define x87_purgecache STEPNAME(x87_purgecache) #define fpu_reflectcache STEPNAME(fpu_reflectcache) +#define fpu_unreflectcache STEPNAME(fpu_unreflectcache) #define CacheTransform STEPNAME(CacheTransform) @@ -1169,6 +1170,7 @@ void mmx_purgecache(dynarec_arm_t* dyn, int ninst, int next, int s1); // purge x87 cache void x87_purgecache(dynarec_arm_t* dyn, int ninst, int next, int s1, int s2, int s3); void fpu_reflectcache(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3); +void fpu_unreflectcache(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3); void fpu_pushcache(dynarec_arm_t* dyn, int ninst, int s1, int not07); void fpu_popcache(dynarec_arm_t* dyn, int ninst, int s1, int not07); diff --git a/src/dynarec/dynarec_native_pass.c b/src/dynarec/dynarec_native_pass.c index d81ef6ee..be9ebd7e 100755 --- a/src/dynarec/dynarec_native_pass.c +++ b/src/dynarec/dynarec_native_pass.c @@ -87,6 +87,7 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr) MESSAGE(LOG_DUMP, "TEST INIT ----\n"); fpu_reflectcache(dyn, ninst, x1, x2, x3); GO_TRACE(x64test_init, 1); + fpu_unreflectcache(dyn, ninst, x1, x2, x3); MESSAGE(LOG_DUMP, "----------\n"); } #ifdef HAVE_TRACE @@ -96,6 +97,7 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr) MESSAGE(LOG_DUMP, "TRACE ----\n"); fpu_reflectcache(dyn, ninst, x1, x2, x3); GO_TRACE(PrintTrace, 1); + fpu_unreflectcache(dyn, ninst, x1, x2, x3); MESSAGE(LOG_DUMP, "----------\n"); } } diff --git a/src/dynarec/rv64/dynarec_rv64_helper.c b/src/dynarec/rv64/dynarec_rv64_helper.c index d031a434..6b44a2b7 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.c +++ b/src/dynarec/rv64/dynarec_rv64_helper.c @@ -745,7 +745,19 @@ void x87_purgecache(dynarec_rv64_t* dyn, int ninst, int next, int s1, int s2, in static void x87_reflectcache(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3) { - x87_stackcount(dyn, ninst, s1); + //Sync top and stack count + int a = dyn->e.x87stack; + if(a) { + // Add x87stack to emu fpu_stack + LW(s2, xEmu, offsetof(x64emu_t, fpu_stack)); + ADDI(s2, s2, a); + SW(s2, xEmu, offsetof(x64emu_t, fpu_stack)); + // Sub x87stack to top, with and 7 + LW(s2, xEmu, offsetof(x64emu_t, top)); + SUBI(s2, s2, a); + ANDI(s2, s2, 7); + SW(s2, xEmu, offsetof(x64emu_t, top)); + } int ret = 0; for (int i=0; (i<8) && (!ret); ++i) if(dyn->e.x87cache[i] != -1) @@ -754,7 +766,9 @@ static void x87_reflectcache(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int return; // prepare offset to fpu => s1 // Get top - LW(s2, xEmu, offsetof(x64emu_t, top)); + if(!a) { + LW(s2, xEmu, offsetof(x64emu_t, top)); + } // loop all cache entries for (int i=0; i<8; ++i) if(dyn->e.x87cache[i]!=-1) { @@ -766,6 +780,23 @@ static void x87_reflectcache(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int } } +static void x87_unreflectcache(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3) +{ + // revert top and stack count + int a = dyn->e.x87stack; + if(a) { + // Sub x87stack to emu fpu_stack + LW(s2, xEmu, offsetof(x64emu_t, fpu_stack)); + SUBI(s2, s2, a); + SW(s2, xEmu, offsetof(x64emu_t, fpu_stack)); + // Add x87stack to top, with and 7 + LW(s2, xEmu, offsetof(x64emu_t, top)); + ADDI(s2, s2, a); + ANDI(s2, s2, 7); + SW(s2, xEmu, offsetof(x64emu_t, top)); + } +} + int x87_get_current_cache(dynarec_rv64_t* dyn, int ninst, int st, int t) { // search in cache first @@ -1698,6 +1729,12 @@ void fpu_reflectcache(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3) sse_reflectcache(dyn, ninst, s1); } +void fpu_unreflectcache(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3) +{ + // need to undo the top and stack tracking that must not be reflected permenatly yet + x87_reflectcache(dyn, ninst, s1, s2, s3); +} + void fpu_reset(dynarec_rv64_t* dyn) { x87_reset(dyn); diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index 4c8651c3..cd795aa6 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -801,6 +801,7 @@ void* rv64_next(x64emu_t* emu, uintptr_t addr); #define x87_purgecache STEPNAME(x87_purgecache) #define sse_purgecache STEPNAME(sse_purgecache) #define fpu_reflectcache STEPNAME(fpu_reflectcache) +#define fpu_unreflectcache STEPNAME(fpu_unreflectcache) #define CacheTransform STEPNAME(CacheTransform) #define rv64_move64 STEPNAME(rv64_move64) @@ -991,6 +992,7 @@ void mmx_purgecache(dynarec_rv64_t* dyn, int ninst, int next, int s1); // purge x87 cache void x87_purgecache(dynarec_rv64_t* dyn, int ninst, int next, int s1, int s2, int s3); void fpu_reflectcache(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3); +void fpu_unreflectcache(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3); void fpu_pushcache(dynarec_rv64_t* dyn, int ninst, int s1, int not07); void fpu_popcache(dynarec_rv64_t* dyn, int ninst, int s1, int not07); |