http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53513
--- Comment #5 from Oleg Endo <olegendo at gcc dot gnu.org> --- (In reply to Oleg Endo from comment #4) > 5) > in some cases preserving FPSCR bits across mode changes is not required (if > I'm not mistaken): > > double func (float a, float b, double c, double d) > { > #pragma STDC FENV_ACCESS ON > > // function entry, PR = double > > // mode switch PR = single > float ab = a + b; > > // mode switch PR = double > double x = ab + c + d; > > // read back FP status bits and do something with it > return x; > > // function exit, PR = double > } > > In this case the mode switch double -> float -> double can be done more > efficiently by pushing the PR = double FPSCR state onto the stack, switch to > PR = single and then switch back to PR = double by popping FPSCR from the > stack. > > However, this must not happen if other FPSCR settings are changed after the > first switch to PR = single, such as invoking a fenv modifying standard > function or changing the FPSCR.FR bit on SH4. If it's OK for a temporary mode switch to clobber other FPSCR bits (such as in the PR = single mode above), it should also be OK to load the FPSCR value from a thread local variable inside the thread-control-block: mov.l @(<disp>, gbr),r0 // r0 = address to fpscr value for a // particular mode setting lds.l @r0+,fpscr // mode switch This would require that any FPSCR setting change is also propagated to the TLS variables. E.g. setting the rounding mode would have to update FPSCR mode values in all such TLS variables. I guess that it would be useful to be able to select an FPSCR value for at least all combinations of FR and SZ bit settings, in other words having a TLS __fpscr_values array with 4 entries. However, it would make things such as toggling FPSCR.FR via frchg inefficient due to the required updates of the TLS variables. Other setting changes such as denorm or rounding mode are probably not so critical.