diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-11-17 15:14:13 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-11-17 15:14:13 +0100 |
| commit | 56298870f68294b76ef963dd2ea0864789b811c3 (patch) | |
| tree | f2512bac77711da04fcb3e420c388c20a86295d5 /src | |
| parent | 48354185dd3ea7fbec26a9078c72816cced1ec3d (diff) | |
| download | box64-56298870f68294b76ef963dd2ea0864789b811c3.tar.gz box64-56298870f68294b76ef963dd2ea0864789b811c3.zip | |
[ARM64_DYNAREC] Only propagate native flags if at least 1 opcode consume them
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_functions.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_functions.c b/src/dynarec/arm64/dynarec_arm64_functions.c index a37434d0..8e0827f0 100644 --- a/src/dynarec/arm64/dynarec_arm64_functions.c +++ b/src/dynarec/arm64/dynarec_arm64_functions.c @@ -858,12 +858,16 @@ static uint8_t getNativeFlagsUsed(dynarec_arm_t* dyn, int start, uint8_t flags) { // propagate and check wich flags are actually used uint8_t used_flags = 0; + int nat_flags_used = 0; int ninst = start; while(ninst<dyn->size) { -//printf_log(LOG_INFO, "getNativeFlagsUsed ninst:%d/%d, flags=%x, used_flags=%x, nat_flags_op_before:%x, nat_flags_op:%x, need_after:%x\n", ninst, start, flags, used_flags, dyn->insts[ninst].nat_flags_op_before, dyn->insts[ninst].nat_flags_op, flag2native(dyn->insts[ninst].x64.need_after)); +//printf_log(LOG_INFO, "getNativeFlagsUsed ninst:%d/%d, flags=%x, used_flags=%x(%d), nat_flags_op_before:%x, nat_flags_op:%x, need_after:%x\n", ninst, start, flags, used_flags, nat_flags_used, dyn->insts[ninst].nat_flags_op_before, dyn->insts[ninst].nat_flags_op, flag2native(dyn->insts[ninst].x64.need_after)); // check if this is an opcode that generate flags but consume flags before if(dyn->insts[ninst].nat_flags_op_before) return 0; + // check if nat flags are used "before" + if(dyn->insts[ninst].use_nat_flags_before) + nat_flags_used = 1; if(dyn->insts[ninst].nat_flags_op==NAT_FLAG_OP_TOUCH && dyn->insts[ninst].use_nat_flags_before) used_flags|=dyn->insts[ninst].use_nat_flags_before&flags; // if the opcode generate flags, return @@ -871,15 +875,18 @@ static uint8_t getNativeFlagsUsed(dynarec_arm_t* dyn, int start, uint8_t flags) if(used_flags&~dyn->insts[ninst].set_nat_flags) { // check partial changes that would destroy flag state if(dyn->insts[ninst].use_nat_flags_before&flags) - return used_flags; + return nat_flags_used?used_flags:0; // but also check if there is before needed return 0; } - return used_flags; + return nat_flags_used?used_flags:0; } // check if there is a callret barrier if(dyn->insts[ninst].x64.has_callret) return 0; + // check if nat flags are used + if(dyn->insts[ninst].use_nat_flags) + nat_flags_used = 1; // check if flags are used, but not the natives ones if(ninst!=start && dyn->insts[ninst].x64.use_flags) { if((flag2native(dyn->insts[ninst].x64.use_flags)&~(dyn->insts[ninst].use_nat_flags))&used_flags) @@ -893,11 +900,11 @@ static uint8_t getNativeFlagsUsed(dynarec_arm_t* dyn, int start, uint8_t flags) if(used_flags&~flag2native(dyn->insts[ninst].x64.gen_flags&dyn->insts[ninst].x64.need_after)) return 0; // partial covert, not supported for now (TODO: this might be fixable) else - return used_flags; // full covert... End of propagation + return nat_flags_used?used_flags:0; // full covert... End of propagation } // check if flags are still needed if(!(flag2native(dyn->insts[ninst].x64.need_after)&flags)) - return used_flags; + return nat_flags_used?used_flags:0; // check if flags are destroyed, cancel the use then if(dyn->insts[ninst].nat_flags_op && (start!=ninst)) return 0; @@ -910,11 +917,11 @@ static uint8_t getNativeFlagsUsed(dynarec_arm_t* dyn, int start, uint8_t flags) if(dyn->insts[ninst].x64.jmp && (jmp!=-1) && (getNominalPred(dyn, jmp)==ninst)) ninst = jmp; else - return used_flags; + return nat_flags_used?used_flags:0; } else ++ninst; } - return used_flags; + return nat_flags_used?used_flags:0; } static void propagateNativeFlags(dynarec_arm_t* dyn, int start) |