I'd like to extend the FPSCR support functions in SH's libgcc.a to include a way for applications to change the bits that GCC doesn't care about (exception handling, denormals, etc). I've come up with this routine and (after much head-banging) managed to test it on real hardware. The idea is that GCC gets to manage the SZ and PR bits, and the application is free to manage the remainder of the bits, without the two interfering with each other.
I chose the single change_fpscr function (I'm not committed to that name) as it allows you to set the multi-bit fields in a single call (mask the whole field, set the new value), but a two-function set/clear pair would work too. At this point, I would like some feedback about the API and how to cleanly (namespace-wise) add it to libgcc.a. static int get_fpscr() { int ret; asm volatile ("sts fpscr,%0" : "=r" (ret)); return ret; } static void put_fpscr(int nv) { asm volatile ("lds %0,fpscr" : : "r" (nv)); } #define FR 0x00200000 #define SZ 0x00100000 #define PR 0x00080000 #define DN 0x00040000 #define RN 0x00000003 #define RN_N 0 #define RN_Z 1 extern int __fpscr_values[2]; void change_fpscr(int off, int on) { int b = get_fpscr(); off = ~off; off |= 0x00180000; on &= ~ 0x00180000; b &= off; b |= on; put_fpscr(b); __fpscr_values[0] &= off; __fpscr_values[0] |= on; __fpscr_values[1] &= off; __fpscr_values[1] |= on; }