Files
bmdhacks 8f67945c9e Fix: RSQRT.S's zero-divisor sign comes from the dividend
Two sign rules, and they are not the same rule. DIV.S takes the xor of
both operands. RSQRT.S takes the DIVIDEND's sign alone -- it divides by
sqrt(|Ft|), so the divisor has no sign left to contribute by the time the
division happens. Both of our engines took Ft's sign, and the arm64
emitter was alone among recompilers in it: x86 recRSQRThelper1 (iFPU.cpp)
has always taken Fs's.

The console rows that separate the rules: rsqrt(+0, -0) is positive and
rsqrt(-0, -0) is negative on silicon; an xor rule, or Ft's sign, flips
both. Fixing the sign moves the arm64 emitter's agreement with the
console and with the x86 JIT, and keeps the two local engines in exact
agreement on the whole zero path.

The MAGNITUDE stays at the fast tier's +/-fMax saturation. Silicon
returns 0x7FFFFFFF there -- the EE's real maximum, one binade up -- but
that is the top-binade compromise shared by every fast-path op, not the
sign rule, and it moves as a class or not at all.

Pinned by EeRecFpuRsqrt.ZeroDivisorSignComesFromTheDividend, six rows
across both zero-sign combinations and nonzero dividends, both engines
diffed. DenormalDivisorTreatedAsZero's expectation flips to the new rule.

Idea by pstef.
2026-08-02 22:35:45 -07:00
..