strauman at slac.stanford.edu
Mon Jun 9 21:44:55 UTC 2008
gregory.d.menke at nasa.gov wrote:
> Joel Sherrill writes:
> > >
> > I can't swear that every architecture RTEMS has been
> > ported to implements this but I know it is a design
> > goal and should be true on at least the PowerPC and
> > SPARC. It is much better to have the FPU disabled
> > when it is not supposed to be used.
> > > Here's one lesson I learned:
> > >
> > > I have seen gcc versions which would silently/implicitly
> > > use the FPU so that making all tasks FP tasks was the only
> > > solution. With this gcc version (don't remember which one it
> > > was) I occasionally had problems with gcc implicitly generating
> > > FP code in ISRs. Only my paranoia (I have the FPU *only* enabled
> > > when FP tasks execute, disabled during exceptions, non-FP tasks
> > > etc.) saved me (I got a trap/exception instead of mysterious
> > > corruption and could then figure out a work-around)...
> > >
> > >
> > The old case we always saw was printf declaring a FP
> > local variable. Even if you never printed a FP number,
> > on some architectures, the presence of that declaration
> > was enough to use the FP.
> > The first time I saw GCC use FP instructions for integer
> > operations was on the HP PA-RISC where FP multiply
> > was preferred over integer multiply for array indexing!!
> > This was in the 1993-4 time frame.
> Depending on the gcc options with which the multilib was compiled, on
> PPC at least gcc can use fp registers for integer operations, even if
> the local float is not present. To overcome this, everything from
> newlib on up must be recompiled with -msoft-float IIRC, which forces gcc
> to build newlib, the cross-compiler, and rtems without using fp
> registers anywhere. This is a tricky problem- much easier to leave the
> fpu support enabled.
I used to think so, too. However, the soft-float and hard-float
ABIs are INCOMPATIBLE, i.e., you MUST NOT link code compiled
with -mhard-float and -msoft-float together. The reason is that the
hard-float ABI says that it sets or clears a bit in CR6 (IIRC) if
FP arguments are passed (or not passed) to a varargs function.
soft-float code does not touch that flag, however.
This means that when a soft-float routine calls a hard-float,
varargs routine the bit in CR6 may be set (since the soft-float
code didn't touch the bit its value is stale, reflecting an old state
left by hard-float code) leading to incorrect behavior.
The good news are that I havent' recently seen gcc aggressively
generating FP code for integer-only operations.
The only correct way of handling this on PPC is
- make all tasks FP-aware
- switch-off FPU during ISRs and exception handlers.
If this causes problems (because of gcc implicitly using the FPU)
then the volatile FP regs have to be saved into IRQ context, too
PS: The very same problems occur with AltiVec, too. However, in the
case of AltiVec I have not found anything that would prohibit
linking -maltivec and -mno-altivec code together (as long as the
stack alignment is 16-byte and you don't pass vector function
arguments between -maltivec and -mno-altivec code).
More information about the users