diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/dynarec_native_pass.c | 9 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00_1.c | 12 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_0f.c | 59 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_functions.c | 18 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_functions.h | 1 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 5 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_pass0.h | 3 |
7 files changed, 68 insertions, 39 deletions
diff --git a/src/dynarec/dynarec_native_pass.c b/src/dynarec/dynarec_native_pass.c index 5df1dce2..43d07719 100644 --- a/src/dynarec/dynarec_native_pass.c +++ b/src/dynarec/dynarec_native_pass.c @@ -176,7 +176,14 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int #if STEP > 0 if(dyn->insts[ninst].x64.has_next && dyn->insts[next].x64.barrier) { if(dyn->insts[next].x64.barrier&BARRIER_FLOAT) { - fpu_purgecache(dyn, ninst, 0, x1, x2, x3); + #ifdef RV64 + uint8_t tmp1, tmp2, tmp3; + if(dyn->insts[next].nat_flags_fusion) get_free_scratch(dyn, next, &tmp1, &tmp2, &tmp3, x1, x2, x3, x4, x5); + else { tmp1=x1; tmp2=x2; tmp3=x3; } + fpu_purgecache(dyn, ninst, 0, tmp1, tmp2, tmp3); + #else + fpu_purgecache(dyn, next, 0, x1, x2, x3); + #endif } if(dyn->insts[next].x64.barrier&BARRIER_FLAGS) { dyn->f.pending = 0; diff --git a/src/dynarec/rv64/dynarec_rv64_00_1.c b/src/dynarec/rv64/dynarec_rv64_00_1.c index 1d2d6dbc..9940d5ec 100644 --- a/src/dynarec/rv64/dynarec_rv64_00_1.c +++ b/src/dynarec/rv64/dynarec_rv64_00_1.c @@ -30,7 +30,7 @@ int isSimpleWrapper(wrapper_t fun); uintptr_t dynarec64_00_1(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog) { uint8_t nextop, opcode; - uint8_t gd, ed; + uint8_t gd, ed, tmp1, tmp2, tmp3; int8_t i8; int32_t i32, tmp; int64_t i64, j64; @@ -308,7 +308,7 @@ uintptr_t dynarec64_00_1(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int break; #define GO(GETFLAGS, NO, YES, NATNO, NATYES, F) \ - READFLAGS_FUSION(F, 1); \ + READFLAGS_FUSION(F, x1, x2, x3, x4, x5); \ i8 = F8S; \ BARRIER(BARRIER_MAYBE); \ JUMP(addr + i8, 1); \ @@ -321,14 +321,14 @@ uintptr_t dynarec64_00_1(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int if (dyn->insts[ninst].nat_flags_fusion) { \ NATIVEJUMP_safe(NATNO, i32); \ } else { \ - B##NO##_safe(x1, i32); \ + B##NO##_safe(tmp1, i32); \ } \ if (dyn->insts[ninst].x64.jmp_insts == -1) { \ if (!(dyn->insts[ninst].x64.barrier & BARRIER_FLOAT)) \ - fpu_purgecache(dyn, ninst, 1, x1, x2, x3); \ + fpu_purgecache(dyn, ninst, 1, tmp1, tmp2, tmp3); \ jump_to_next(dyn, addr + i8, 0, ninst, rex.is32bits); \ } else { \ - CacheTransform(dyn, ninst, cacheupd, x1, x2, x3); \ + CacheTransform(dyn, ninst, cacheupd, tmp1, tmp2, tmp3); \ i32 = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address - (dyn->native_size); \ B(i32); \ } \ @@ -338,7 +338,7 @@ uintptr_t dynarec64_00_1(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int if (dyn->insts[ninst].nat_flags_fusion) { \ NATIVEJUMP_safe(NATYES, i32); \ } else { \ - B##YES##_safe(x1, i32); \ + B##YES##_safe(tmp1, i32); \ } \ } GOCOND(0x70, "J", "ib"); diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c index d0d79725..9838d9b8 100644 --- a/src/dynarec/rv64/dynarec_rv64_0f.c +++ b/src/dynarec/rv64/dynarec_rv64_0f.c @@ -36,6 +36,7 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni uint8_t wb1, wback, wb2, gback; uint8_t eb1, eb2; uint8_t gb1, gb2; + uint8_t tmp1, tmp2, tmp3; int32_t i32, i32_; int cacheupd = 0; int v0, v1; @@ -899,30 +900,30 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } break; -#define GO(GETFLAGS, NO, YES, NATNO, NATYES, F) \ - READFLAGS_FUSION(F, 0); \ - if (!dyn->insts[ninst].nat_flags_fusion) { \ - GETFLAGS; \ - } \ - nextop = F8; \ - GETGD; \ - if (MODREG) { \ - ed = TO_NAT((nextop & 7) + (rex.b << 3)); \ - if (dyn->insts[ninst].nat_flags_fusion) { \ - NATIVEJUMP(NATNO, 8); \ - } else { \ - B##NO(x1, 8); \ - } \ - MV(gd, ed); \ - } else { \ - addr = geted(dyn, addr, ninst, nextop, &ed, x2, x4, &fixedaddress, rex, NULL, 1, 0); \ - if (dyn->insts[ninst].nat_flags_fusion) { \ - NATIVEJUMP(NATNO, 8); \ - } else { \ - B##NO(x1, 8); \ - } \ - LDxw(gd, ed, fixedaddress); \ - } \ +#define GO(GETFLAGS, NO, YES, NATNO, NATYES, F) \ + READFLAGS_FUSION(F, x1, x2, x3, x4, x5); \ + if (!dyn->insts[ninst].nat_flags_fusion) { \ + GETFLAGS; \ + } \ + nextop = F8; \ + GETGD; \ + if (MODREG) { \ + ed = TO_NAT((nextop & 7) + (rex.b << 3)); \ + if (dyn->insts[ninst].nat_flags_fusion) { \ + NATIVEJUMP(NATNO, 8); \ + } else { \ + B##NO(tmp1, 8); \ + } \ + MV(gd, ed); \ + } else { \ + addr = geted(dyn, addr, ninst, nextop, &ed, tmp2, tmp3, &fixedaddress, rex, NULL, 1, 0); \ + if (dyn->insts[ninst].nat_flags_fusion) { \ + NATIVEJUMP(NATNO, 8); \ + } else { \ + B##NO(tmp1, 8); \ + } \ + LDxw(gd, ed, fixedaddress); \ + } \ if (!rex.w) ZEROUP(gd); GOCOND(0x40, "CMOV", "Gd, Ed"); @@ -1671,7 +1672,7 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni SD(x3, wback, fixedaddress); break; #define GO(GETFLAGS, NO, YES, NATNO, NATYES, F) \ - READFLAGS_FUSION(F, 1); \ + READFLAGS_FUSION(F, x1, x2, x3, x4, x5); \ i32_ = F32S; \ if (rex.is32bits) \ j64 = (uint32_t)(addr + i32_); \ @@ -1688,14 +1689,14 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni if (dyn->insts[ninst].nat_flags_fusion) { \ NATIVEJUMP_safe(NATNO, i32); \ } else { \ - B##NO##_safe(x1, i32); \ + B##NO##_safe(tmp1, i32); \ } \ if (dyn->insts[ninst].x64.jmp_insts == -1) { \ if (!(dyn->insts[ninst].x64.barrier & BARRIER_FLOAT)) \ - fpu_purgecache(dyn, ninst, 1, x1, x2, x3); \ + fpu_purgecache(dyn, ninst, 1, tmp1, tmp2, tmp3); \ jump_to_next(dyn, j64, 0, ninst, rex.is32bits); \ } else { \ - CacheTransform(dyn, ninst, cacheupd, x1, x2, x3); \ + CacheTransform(dyn, ninst, cacheupd, tmp1, tmp2, tmp3); \ i32 = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address - (dyn->native_size); \ B(i32); \ } \ @@ -1705,7 +1706,7 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni if (dyn->insts[ninst].nat_flags_fusion) { \ NATIVEJUMP_safe(NATYES, i32); \ } else { \ - B##YES##_safe(x1, i32); \ + B##YES##_safe(tmp1, i32); \ } \ } GOCOND(0x80, "J", "Id"); diff --git a/src/dynarec/rv64/dynarec_rv64_functions.c b/src/dynarec/rv64/dynarec_rv64_functions.c index 22dda2ef..d74effaf 100644 --- a/src/dynarec/rv64/dynarec_rv64_functions.c +++ b/src/dynarec/rv64/dynarec_rv64_functions.c @@ -812,3 +812,21 @@ void updateNativeFlags(dynarec_rv64_t* dyn) dyn->insts[i].nat_flags_fusion = 0; } } + +void get_free_scratch(dynarec_rv64_t* dyn, int ninst, uint8_t* tmp1, uint8_t* tmp2, uint8_t* tmp3, uint8_t s1, uint8_t s2, uint8_t s3, uint8_t s4, uint8_t s5) +{ + uint8_t n1 = dyn->insts[ninst].nat_flags_op1; + uint8_t n2 = dyn->insts[ninst].nat_flags_op2; + uint8_t tmp[5] = {0}; + int idx = 0; + #define GO(s) if((s!=n1) && (s!=n2)) tmp[idx++] = s + GO(s1); + GO(s2); + GO(s3); + GO(s4); + GO(s5); + #undef GO + *tmp1 = tmp[0]; + *tmp2 = tmp[1]; + *tmp3 = tmp[2]; +} \ No newline at end of file diff --git a/src/dynarec/rv64/dynarec_rv64_functions.h b/src/dynarec/rv64/dynarec_rv64_functions.h index b61b904a..668c24a9 100644 --- a/src/dynarec/rv64/dynarec_rv64_functions.h +++ b/src/dynarec/rv64/dynarec_rv64_functions.h @@ -68,4 +68,5 @@ void fpu_reset_ninst(dynarec_native_t* dyn, int ninst); int fpu_is_st_freed(dynarec_native_t* dyn, int ninst, int st); void updateNativeFlags(dynarec_rv64_t* dyn); +void get_free_scratch(dynarec_rv64_t* dyn, int ninst, uint8_t* tmp1, uint8_t* tmp2, uint8_t* tmp3, uint8_t s1, uint8_t s2, uint8_t s3, uint8_t s4, uint8_t s5); #endif //__DYNAREC_RV64_FUNCTIONS_H__ diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index 2127dfec..ee61c13d 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -1021,7 +1021,10 @@ #endif #ifndef READFLAGS_FUSION -#define READFLAGS_FUSION(A, checkbarrier) READFLAGS(A) +#define READFLAGS_FUSION(A, s1, s2, s3, s4, s5) \ + if(dyn->insts[ninst].nat_flags_fusion) get_free_scratch(dyn, ninst, &tmp1, &tmp2, &tmp3, s1, s2, s3, s4, s5); \ + else { tmp1=s1; tmp2=s2; tmp3=s3; } \ + READFLAGS(A) #endif #define NAT_FLAGS_OPS(op1, op2) \ diff --git a/src/dynarec/rv64/dynarec_rv64_pass0.h b/src/dynarec/rv64/dynarec_rv64_pass0.h index 3747a7e2..3ecaad3e 100644 --- a/src/dynarec/rv64/dynarec_rv64_pass0.h +++ b/src/dynarec/rv64/dynarec_rv64_pass0.h @@ -14,7 +14,7 @@ dyn->f.dfnone = 1; \ dyn->f.pending = SF_SET -#define READFLAGS_FUSION(A, checkbarrier) \ +#define READFLAGS_FUSION(A, s1, s2, s3, s4, s5) \ if (box64_dynarec_nativeflags && ninst > 0 && !dyn->insts[ninst - 1].nat_flags_nofusion) { \ if ((A) == (X_ZF)) \ dyn->insts[ninst].nat_flags_fusion = 1; \ @@ -22,7 +22,6 @@ dyn->insts[ninst].nat_flags_fusion = 1; \ else if (dyn->insts[ninst - 1].nat_flags_sign && ((A) == (X_SF | X_OF) || (A) == (X_SF | X_OF | X_ZF))) \ dyn->insts[ninst].nat_flags_fusion = 1; \ - if (checkbarrier && fpu_needpurgecache(dyn, ninst)) dyn->insts[ninst].nat_flags_fusion = 0; \ } \ READFLAGS(A); |