mirror of
https://github.com/ARMSX2/ARMSX2.git
synced 2026-08-24 16:50:16 -07:00
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.