Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JIT64: Fix fmul rounding issues #834

Merged
merged 2 commits into from Aug 24, 2014

Conversation

FioraAeterna
Copy link
Contributor

Thanks to magumagu's softfp experiments, we know a lot more about the Wii's
strange floating point unit than we used to. In particular, when doing a
single-precision floating point multiply (fmulsx), it rounds the right hand
side's mantissa so as to lose the low 28 bits (of the 53-bit mantissa).

Emulating this behavior in Dolphin fixes a bunch of issues with games that
require extremely precise emulation of floating point hardware, especially
game replays. Fortunately, we can do this with rather little CPU cost; just ~5
extra instructions per multiply, instead of the vast load of a pure-software
float implementation.

This doesn't make floating-point behavior at all perfect. I still suspect
fmadd rounding might not be quite right, since the Wii uses fused instructions
and Dolphin doesn't, and NaN/infinity/exception handling is probably off in
various ways... but it's definitely way better than before.

This appears to fix replays in Mario Kart Wii, Mario Kart Double Dash, and
Super Smash Brothers Brawl. I wouldn't be surprised if it fixes a bunch of
other stuff too.

The changes to instructions other than fmulsx may not be strictly necessary,
but I included them for completeness, since it feels wrong to fix some
instructions but not others, since some games we didn't test might rely on
them.

@JMC47
Copy link
Contributor

JMC47 commented Aug 19, 2014

Verified a bunch of Mario Kart Wii replays, Some Mario Kart Double Dash replays, and many Super Smash Bros. Brawl Replays. Also seemed to fix the fact that Mario keeps sticking to angled surfaces on Super Mario Galaxy 2 when going across certain gravity changes in cylindrical gravity fields.

SoftFP did other stuff that fixed F-Zero GX and Dave Mirra Pro BMX's replays. This does not seem to affect them in any way, unfortunately. The only thing I was able to acertain is that it is something in the interpreter, not the JIT.

@Linktothepast
Copy link
Contributor

The super guide of DKCR seems to work fine too. See https://wiki.dolphin-emu.org/index.php?title=SF8E01

@JMC47
Copy link
Contributor

JMC47 commented Aug 19, 2014

Latest update fixes F-Zero GX and all the other issues I was running into.

rPS1(_inst.FD) = ForceSingle( -NI_msub( rPS1(_inst.FA), rPS1(_inst.FC), rPS1(_inst.FB) ) );
double c0 = Force25Bit(rPS0(_inst.FC));
double c1 = Force25Bit(rPS1(_inst.FC));
rPS0(_inst.FD) = ForceSingle( -NI_msub( rPS0(_inst.FA), c0, rPS0(_inst.FB) ) );

This comment was marked as off-topic.

This comment was marked as off-topic.

This comment was marked as off-topic.

@@ -111,24 +129,25 @@ void Jit64::fmaddXX(UGeckoInstruction inst)
int d = inst.FD;

fpr.Lock(a, b, c, d);
MOVSD(XMM0, fpr.R(a));
MOVSD(XMM0, fpr.R(c));
Force25BitPrecision(XMM0, XMM1);

This comment was marked as off-topic.

This comment was marked as off-topic.

This comment was marked as off-topic.

@Tilka
Copy link
Member

Tilka commented Aug 20, 2014

I don't really know anything about proper PPC-ish float rounding, so I'll take the easy way out and say:

If it passes more tests than before, it's good. In other words, hwtest pls :)

@JMC47
Copy link
Contributor

JMC47 commented Aug 22, 2014

I checked the Hardware tests, and on Master the CPU test that magumagu gave me for the softFP rounding issues goes off screen and I can't copy all of the errors.

On this branch, it's slightly better in that the number of problems seems to fit on the screen. I don't know if I have the latest version of the CPU test for softFP.

@delroth
Copy link
Member

delroth commented Aug 24, 2014

Could you rebase and fix the OS X build issues?

Thanks to magumagu's softfp experiments, we know a lot more about the Wii's
strange floating point unit than we used to. In particular, when doing a
single-precision floating point multiply (fmulsx), it rounds the right hand
side's mantissa so as to lose the low 28 bits (of the 53-bit mantissa).

Emulating this behavior in Dolphin fixes a bunch of issues with games that
require extremely precise emulation of floating point hardware, especially
game replays. Fortunately, we can do this with rather little CPU cost; just ~5
extra instructions per multiply, instead of the vast load of a pure-software
float implementation.

This doesn't make floating-point behavior at all perfect. I still suspect
fmadd rounding might not be quite right, since the Wii uses fused instructions
and Dolphin doesn't, and NaN/infinity/exception handling is probably off in
various ways... but it's definitely way better than before.

This appears to fix replays in Mario Kart Wii, Mario Kart Double Dash, and
Super Smash Brothers Brawl. I wouldn't be surprised if it fixes a bunch of
other stuff too.

The changes to instructions other than fmulsx may not be strictly necessary,
but I included them for completeness, since it feels wrong to fix some
instructions but not others, since some games we didn't test might rely on
them.
delroth added a commit that referenced this pull request Aug 24, 2014
@delroth delroth merged commit ebf1b98 into dolphin-emu:master Aug 24, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
7 participants