Arm64: Don't clobber NZCV in CondJump

Again we need to handle this one specially because the dispatcher can't insert
restore code after the branch. It should be optimized in the near future, don't
worry.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
This commit is contained in:
Alyssa Rosenzweig committed 2023-11-09 09:40:51 -04:00
1 parent b3055523b4
commit 8f7e393ffb
1 file changed
+9 -1
@@ -145,6 +145,9 @@ DEF_OP(CondJump) {
LOGMAN_THROW_A_FMT(IsGPR(Op->Cmp1.ID()), "CondJump: Expected GPR");
cbnz(Size, GetReg(Op->Cmp1.ID()), TrueTargetLabel);
} else {
// FIXME: We should split up this op to avoid the NZCV spill/fill dance.
mrs(TMP1, ARMEmitter::SystemRegister::NZCV);
if (IsGPR(Op->Cmp1.ID())) {
if (tests) {
if (isConst) {
@@ -165,7 +168,12 @@ DEF_OP(CondJump) {
LOGMAN_MSG_A_FMT("CondJump: Expected GPR or FPR");
}
b(MapBranchCC(Op->Cond), TrueTargetLabel);
// Restore NZCV
cset(Size, TMP2, MapBranchCC(Op->Cond));
msr(ARMEmitter::SystemRegister::NZCV, TMP1);
// Non-NZCV using branch so we can keep the guest value
cbnz(Size, TMP2, TrueTargetLabel);
}
PendingTargetLabel = &JumpTargets.try_emplace(Op->FalseBlock.ID()).first->second;