diff options
| author | Mai <mai.iam2048@gmail.com> | 2023-12-10 12:19:41 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-12-10 12:19:41 -0500 |
| commit | db1620db423d590cb862fdc6f0dc866336f0d6f5 (patch) | |
| tree | f940dc5bcb3c418841cfed84ae9a79d8083f6503 /Source/Core | |
| parent | d272b0ef84e62ad91bbdc0c5ec10f2f772d455ac (diff) | |
| parent | 13a4f1b799387b3d53a1a1e94fcf742a9e39d018 (diff) | |
Merge pull request #12377 from JosJuice/jitarm64-a-d-discard-guard
JitArm64: Guard against discarding a in lmw/stmw
Diffstat (limited to 'Source/Core')
| -rw-r--r-- | Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp index d42fb5b251..4c8713b040 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStore.cpp @@ -541,6 +541,19 @@ void JitArm64::lmw(UGeckoInstruction inst) if (!a_is_addr_base_reg) MOV(addr_base_reg, addr_reg); + BitSet32 gprs_to_discard{}; + if (!jo.memcheck) + { + gprs_to_discard = js.op->gprDiscardable; + if (gprs_to_discard[a]) + { + if (a_is_addr_base_reg) + gprs_to_discard[a] = false; + else + gpr.DiscardRegisters(BitSet32{int(a)}); + } + } + BitSet32 gprs_to_flush = ~js.op->gprInUse & BitSet32(0xFFFFFFFFU << d); if (!js.op->gprInUse[a]) { @@ -592,7 +605,7 @@ void JitArm64::lmw(UGeckoInstruction inst) // after this instruction, flush registers that would be flushed after this instruction anyway. // // We try to store two registers at a time when possible to let the register cache use STP. - if (!jo.memcheck && js.op->gprDiscardable[i]) + if (gprs_to_discard[i]) { gpr.DiscardRegisters(BitSet32{int(i)}); } @@ -645,6 +658,19 @@ void JitArm64::stmw(UGeckoInstruction inst) if (!a_is_addr_base_reg) MOV(addr_base_reg, addr_reg); + BitSet32 gprs_to_discard{}; + if (!jo.memcheck) + { + gprs_to_discard = js.op->gprDiscardable; + if (gprs_to_discard[a]) + { + if (a_is_addr_base_reg) + gprs_to_discard[a] = false; + else + gpr.DiscardRegisters(BitSet32{int(a)}); + } + } + const BitSet32 dirty_gprs_to_flush_unmasked = ~js.op->gprInUse & gpr.GetDirtyGPRs(); BitSet32 dirty_gprs_to_flush = dirty_gprs_to_flush_unmasked & BitSet32(0xFFFFFFFFU << s); if (dirty_gprs_to_flush_unmasked[a]) @@ -692,7 +718,7 @@ void JitArm64::stmw(UGeckoInstruction inst) // after this instruction, flush registers that would be flushed after this instruction anyway. // // We try to store two registers at a time when possible to let the register cache use STP. - if (!jo.memcheck && js.op->gprDiscardable[i]) + if (gprs_to_discard[i]) { gpr.DiscardRegisters(BitSet32{int(i)}); } |
