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

Optimisations. #4

Merged
merged 3 commits into from
Jan 23, 2014
Merged

Optimisations. #4

merged 3 commits into from
Jan 23, 2014

Conversation

Nebuleon
Copy link
Contributor

I attach some commits that optimise some rather common cases in interpreted opcodes:

  • floating-point operations setting the rounding mode when that's not needed;
  • inter-block branches (J*_OUT and B*_OUT) targetting the physical addresses (0x80000000 inclusive to 0xC0000000 exclusive).

Setting the rounding mode on some host architectures (including x86, according to <http://www.mega-nerd.com/FPcast/>) empties the floating-point unit's pipeline, resulting in poorer performance. Omitting the rounding mode before exact operations restores some performance.

Affected opcodes are CVT.W.S, CVT.W.D, CVT.L.S, CVT.L.D, ABS.S, MOV.S, NEG.S, ABS.D, MOV.D and NEG.D.
The rounding mode is completely unneeded when converting from W (32-bit integer) or S (32-bit floating-point) to D (64-bit floating-point), and is actually unused on MIPS processors.

Quoting from the MIPS Programmer's Manual, volume 2, for CVT.D.fmt:
The value in FPR fs, in format fmt, is converted to a value in double floating point format and rounded according to the current rounding mode in FCSR. The result is placed in FPR fd. If fmt is S or W, then the operation is always exact.
@richard42
Copy link
Member

Hi Nebuleon, thanks for this patch. In reviewing the changes, I think that the following instructions still need to retain the rounding mode set function call:

cvt_w_s
cvt_w_d
cvt_l_s
cvt_l_d

These instructions perform a conversion from floating-point to integer, which loses precision. As such, I think that their results will be affected by the current rounding mode. Aside from this, the other changes look good.

@Nebuleon
Copy link
Contributor Author

cvt_[int]_[float] call into one of sixteen functions depending on the value of the N64 FCR31, each of which in turn calls one of eight C standard library functions (truncf, roundf, floorf, ceilf, trunc, round, floor, and ceil) which set their own native rounding modes as implied by their names.

Because none of the sixteen functions actually needs the rounding mode to already be set, the issue is not that the rounding mode is not needed, it's that the rounding mode is needlessly set twice. I am sorry for the confusion and the lumping into the same commit.

Reference:

M64P_FPU_INLINE void cvt_w_s(float *source,int *dest)

richard42 added a commit that referenced this pull request Jan 23, 2014
@richard42 richard42 merged commit 0356e78 into mupen64plus:master Jan 23, 2014
@richard42
Copy link
Member

I see, thanks for the explanation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants