summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorJosJuice <josjuice@gmail.com>2025-08-23 15:18:54 +0200
committerJosJuice <josjuice@gmail.com>2026-01-18 20:02:49 +0100
commit6ac7ffcdd78cac3036a6cb59d13b057bcac584bf (patch)
treeb6000180be8b147763bc79dc46c66965e0d8b736 /Source/Core
parentd5067b62768b0621ad8fe214a9a690aab91050d6 (diff)
Jit64: Return FixupBranch from HandleNaNs
This will be used in the next commit to skip running code that's unnecessary when the result is NaN.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit.h7
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit_FloatingPoint.cpp43
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit_Paired.cpp9
3 files changed, 39 insertions, 20 deletions
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.h b/Source/Core/Core/PowerPC/Jit64/Jit.h
index ad5db1fa10..d9030116d8 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit.h
+++ b/Source/Core/Core/PowerPC/Jit64/Jit.h
@@ -153,9 +153,10 @@ public:
void FinalizeSingleResult(Gen::X64Reg output, const Gen::OpArg& input, bool packed = true,
bool duplicate = false);
void FinalizeDoubleResult(Gen::X64Reg output, const Gen::OpArg& input);
- void HandleNaNs(UGeckoInstruction inst, Gen::X64Reg xmm, Gen::X64Reg clobber,
- std::optional<Gen::OpArg> Ra, std::optional<Gen::OpArg> Rb,
- std::optional<Gen::OpArg> Rc);
+ [[nodiscard]] Gen::FixupBranch HandleNaNs(UGeckoInstruction inst, Gen::X64Reg xmm,
+ Gen::X64Reg clobber, std::optional<Gen::OpArg> Ra,
+ std::optional<Gen::OpArg> Rb,
+ std::optional<Gen::OpArg> Rc);
void MultiplyImmediate(u32 imm, int a, int d, bool overflow);
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_FloatingPoint.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_FloatingPoint.cpp
index 5e7802ff67..2ef3788d51 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit_FloatingPoint.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/Jit_FloatingPoint.cpp
@@ -93,8 +93,9 @@ void Jit64::FinalizeDoubleResult(X64Reg output, const OpArg& input)
SetFPRFIfNeeded(input, false);
}
-void Jit64::HandleNaNs(UGeckoInstruction inst, X64Reg xmm, X64Reg clobber, std::optional<OpArg> Ra,
- std::optional<OpArg> Rb, std::optional<OpArg> Rc)
+FixupBranch Jit64::HandleNaNs(UGeckoInstruction inst, X64Reg xmm, X64Reg clobber,
+ std::optional<OpArg> Ra, std::optional<OpArg> Rb,
+ std::optional<OpArg> Rc)
{
// | PowerPC | x86
// ---------------------+----------+---------
@@ -104,9 +105,6 @@ void Jit64::HandleNaNs(UGeckoInstruction inst, X64Reg xmm, X64Reg clobber, std::
// Dragon Ball: Revenge of King Piccolo requires generated NaNs
// to be positive, so we'll have to handle them manually.
- if (!m_accurate_nans)
- return;
-
if (inst.OPCD != 4)
{
// not paired-single
@@ -140,7 +138,7 @@ void Jit64::HandleNaNs(UGeckoInstruction inst, X64Reg xmm, X64Reg clobber, std::
FixupBranch done = J(Jump::Near);
SwitchToNearCode();
- SetJumpTarget(done);
+ return done;
}
else
{
@@ -217,7 +215,7 @@ void Jit64::HandleNaNs(UGeckoInstruction inst, X64Reg xmm, X64Reg clobber, std::
FixupBranch done = J(Jump::Near);
SwitchToNearCode();
- SetJumpTarget(done);
+ return done;
}
}
@@ -329,14 +327,21 @@ void Jit64::fp_arith(UGeckoInstruction inst)
}
}
- switch (inst.SUBOP5)
+ if (m_accurate_nans)
{
- case 18:
- HandleNaNs(inst, dest, XMM0, Ra, Rarg2, std::nullopt);
- break;
- case 25:
- HandleNaNs(inst, dest, XMM0, Ra, std::nullopt, Rarg2);
- break;
+ std::optional<FixupBranch> handled_nans;
+ switch (inst.SUBOP5)
+ {
+ case 18:
+ handled_nans = HandleNaNs(inst, dest, XMM0, Ra, Rarg2, std::nullopt);
+ break;
+ case 25:
+ handled_nans = HandleNaNs(inst, dest, XMM0, Ra, std::nullopt, Rarg2);
+ break;
+ }
+
+ if (handled_nans)
+ SetJumpTarget(*handled_nans);
}
if (single)
@@ -585,8 +590,14 @@ void Jit64::fmaddXX(UGeckoInstruction inst)
DEBUG_ASSERT(!preserve_d);
}
- // If packed, the clobber register must be XMM0. If not packed, the clobber register is unused.
- HandleNaNs(inst, result_xmm, XMM0, Ra, Rb, madds_accurate_nans ? R(Rc_duplicated) : Rc);
+ if (m_accurate_nans)
+ {
+ // If packed, the clobber register must be XMM0. If not packed, the clobber register is unused.
+ const FixupBranch handled_nans =
+ HandleNaNs(inst, result_xmm, XMM0, Ra, Rb, madds_accurate_nans ? R(Rc_duplicated) : Rc);
+
+ SetJumpTarget(handled_nans);
+ }
if (single)
FinalizeSingleResult(Rd, R(result_xmm), packed, true);
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_Paired.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_Paired.cpp
index 930757cdad..8e44eb78b4 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit_Paired.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/Jit_Paired.cpp
@@ -100,12 +100,19 @@ void Jit64::ps_muls(UGeckoInstruction inst)
default:
PanicAlertFmt("ps_muls WTF!!!");
}
+
if (round_input)
Force25BitPrecision(XMM1, R(Rc_duplicated), XMM0);
else if (XMM1 != Rc_duplicated)
MOVAPD(XMM1, Rc_duplicated);
MULPD(XMM1, Ra);
- HandleNaNs(inst, XMM1, XMM0, Ra, std::nullopt, Rc_duplicated);
+
+ if (m_accurate_nans)
+ {
+ const FixupBranch handled_nans = HandleNaNs(inst, XMM1, XMM0, Ra, std::nullopt, Rc_duplicated);
+ SetJumpTarget(handled_nans);
+ }
+
FinalizeSingleResult(Rd, R(XMM1));
}