SH-4 Mode Bits
The semantics of several instructions of the SH-4 are subject to the control of mode bits in the floating-point control register (FPSCR). These bits include FR, PR, and SZ. These bits dictate which floating-point register bank is currently active and the size of floating point register operands - 32 or 64 bits.
The SH-4 specification dictates specific rules about the state of these mode bits on entry to and exit from function calls. Inline assembly code, which modifies the values of these bits, must be careful to avoid the violation of these rules and should follow these rules as if they in fact were separate function calls.
Specifically, 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
Elements of the SHx __asm Block | The __asm Keyword in SHx Inline Assembly | __asm Restrictions in SHx Inline Assembly | Constants in SHx Inline Assembly | Symbols and Labels in SHx Inline Assembly | SHx Inline Assembly Parameters | Branching in SHx Inline Assembly
Last updated on Thursday, April 08, 2004
© 1992-2003 Microsoft Corporation. All rights reserved.