SH-4 Mode Bits (Windows CE 5.0)
Mode bits in the floating-point control register (FPSCR) control several instructions of the SH-4. The mode bits FR, PR, and SZ dictate which floating-point register bank is currently active and whether floating point register operands are 32 or 64 bits.
Before control leaves the scope of an inline assembly sequence, the state of the mode bits must be returned to their value on entry to the scope. Failure to maintain consistency in these mode bits may result in undefined and unanticipated program failures.
The following code fragment illustrates how to change and restore the PR bit in the FPSCR control register.
// Compute x+y+z --> result
float add_trig(float x, float y, float z)
{
float result;
__asm("lds r4, fpul ; load lw-part of x to fpul \n"
"fsts fpul, fr5 ; copy lw-part of x to fr5 \n"
"lds r5, fpul ; load hi-part of x to fpul \n"
"fsts fpul, fr4 ; copy hi-part of x to fr4 \n"
"lds r6, fpul ; load lw-part of y to fpul \n"
"fsts fpul, fr7 ; copy lw-part of y to fr7 \n"
"lds r7, fpul ; load hi-part of y to fpul \n"
"fsts fpul, fr6 ; copy hi-part of y to fr6 \n"
"mov.l @(16,sp),r0 ; load lw-part of z to r0 \n"
"lds r0, fpul ; \n"
"fsts fpul, fr9 ; copy lw-part of z to fr9 \n"
"mov.l @(20,sp),r0 ; load hi-part of z to r0 \n"
"lds r0, fpul ; \n"
"fsts fpul, fr8 ; copy hi-part of z to fr8 \n"
"mov #8, r0 ; prepare to mask the pr bit \n"
"shll16 r0 ; \n"
"sts fpscr, r1 ; \n"
"xor r0, r1 ; toggle pr bit \n"
"lds r1, fpscr ; turn-on pr bit \n"
"fcnvds dr4, fpul ; convert x double to single precision\n"
"fsts fpul, fr4 ; store float x in fr4\n"
"fcnvds dr6, fpul ; convert y double to single precision\n"
"fsts fpul, fr5 ; store float y in fr5\n"
"fcnvds dr8, fpul ; convert z double to single precision\n"
"fsts fpul, fr6 ; store float z in fr6\n"
"xor r0, r1 ; toggle pr bit \n"
"lds r1, fpscr ; turn-off pr bit\n"
"fadd fr4, fr5 ; compute x+y\n"
"fadd fr5, fr6 ; compute x+y+z \n"
"mov.l @(24,sp), r0 ; load result address\n"
"fmov.s fr6, @r0 ; store fr6 into result addr\n",
x, // promoted to double and passed in r4 and r5
y, // promoted to double and passed in r6 and r7
z, // promoted to double and passed in @(16,sp)
// and @(20,sp)
&result); // pointer to result passed in @(24,sp)
return result;
}
void main()
{
float retval = add_trig(1.0f, 2.0f,3.0f);
printf("%g\n", retval);
}
See Also
SH-4 Inline Assembly Language | SH-4 Inline Assembly Code Examples
Send Feedback on this topic to the authors