powerpc: avoiding lfd/stfd for 64 bit integer load/stores

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

powerpc: avoiding lfd/stfd for 64 bit integer load/stores

Rasmus Villemoes-3
I'm trying to build the VxWorks kernel using gcc 7.3. It builds and
boots, but I'm having a problem with use of fpr f0 from interrupt context.

An ISR ends up calling a function taking an unsigned long long, which is
passed on to another function; the assembly code for shuffling that
argument around is

  153698:       c8 01 00 68     lfd     f0,104(r1)
  15369c:       d8 01 00 18     stfd    f0,24(r1)

and the first instruction triggers an exception. This is apparently gcc
being clever and using just two instructions for loading/storing 64
bits. It seems I can avoid the generation of these instructions with
-msoft-float, but that's somewhat of a big hammer, as I do want to use
the FPU for the stuff running in task context. I suppose I could try to
apply -msoft-float just to the TUs that might be called from interrupts,
but what I'm looking for is a switch to avoid using FPRs for integers
(i.e., it's fine to use the FPU when the source code actually works on
floats or doubles). Is there such a switch I'm overlooking?

Thanks,
Rasmus
Reply | Threaded
Open this post in threaded view
|

Re: powerpc: avoiding lfd/stfd for 64 bit integer load/stores

Segher Boessenkool
Hi Rasmus,

On Wed, Nov 21, 2018 at 11:05:38AM +0000, Rasmus Villemoes wrote:

> I'm trying to build the VxWorks kernel using gcc 7.3. It builds and
> boots, but I'm having a problem with use of fpr f0 from interrupt context.
>
> An ISR ends up calling a function taking an unsigned long long, which is
> passed on to another function; the assembly code for shuffling that
> argument around is
>
>   153698:       c8 01 00 68     lfd     f0,104(r1)
>   15369c:       d8 01 00 18     stfd    f0,24(r1)
>
> and the first instruction triggers an exception. This is apparently gcc
> being clever and using just two instructions for loading/storing 64
> bits. It seems I can avoid the generation of these instructions with
> -msoft-float, but that's somewhat of a big hammer, as I do want to use
> the FPU for the stuff running in task context. I suppose I could try to
> apply -msoft-float just to the TUs that might be called from interrupts,
> but what I'm looking for is a switch to avoid using FPRs for integers
> (i.e., it's fine to use the FPU when the source code actually works on
> floats or doubles). Is there such a switch I'm overlooking?

There is no such switch.  Implementing such a switch would be hard; for
example, the convert-float-to-integer instructions need to store an integer
in a floating point register.

Compiling translation units with different needs, with different flags, is
the way to go.  -msoft-float means "do not use the FPRs".


Segher
Reply | Threaded
Open this post in threaded view
|

Re: powerpc: avoiding lfd/stfd for 64 bit integer load/stores

Peter Bergner-4
On 11/21/18 7:13 AM, Segher Boessenkool wrote:
> There is no such switch.  Implementing such a switch would be hard; for
> example, the convert-float-to-integer instructions need to store an integer
> in a floating point register.
>
> Compiling translation units with different needs, with different flags, is
> the way to go.  -msoft-float means "do not use the FPRs".

I agree with Segher here.  I'll note though that -msoft-float and -mhard-float
are different ABIs.  However, if you don't call a function across the soft-float
to hard-float barrier that has floating point arguments or floating point
return value, you should be fine.

Peter

Reply | Threaded
Open this post in threaded view
|

Re: powerpc: avoiding lfd/stfd for 64 bit integer load/stores

Rasmus Villemoes-3
Hi Segher and Peter

On 21/11/2018 17.52, Peter Bergner wrote:
> On 11/21/18 7:13 AM, Segher Boessenkool wrote:
>> There is no such switch.  Implementing such a switch would be hard; for
>> example, the convert-float-to-integer instructions need to store an integer
>> in a floating point register.

Thanks for the answer. I accept that it would be hard to do such a
switch, though I don't think I understand that example. Why would gcc
ever create an int-to-float or float-to-int unless the source code
actually used float or double?

>> Compiling translation units with different needs, with different flags, is
>> the way to go.  -msoft-float means "do not use the FPRs".
>
> I agree with Segher here.  I'll note though that -msoft-float and -mhard-float
> are different ABIs.  However, if you don't call a function across the soft-float
> to hard-float barrier that has floating point arguments or floating point
> return value, you should be fine.

We may have to do it that way, then. But I would hope to have some help
from the compiler to detect ABI violations, or generation of soft-float
code. We could build everything with -msoft-float, and all such code
should be forbidden from using float/double/long double in any way -
calling functions taking those, defining variables, casting to/from, ...
either via a new warning, or a hypothetical '-mno-float' [which I see
actually exists for MIPS]. Then we could selectively turn on
-mhard-float for the few TUs that actually need that.

Thanks,
Rasmus
Reply | Threaded
Open this post in threaded view
|

Re: powerpc: avoiding lfd/stfd for 64 bit integer load/stores

Segher Boessenkool
Hi!

On Thu, Nov 22, 2018 at 10:38:41AM +0000, Rasmus Villemoes wrote:

> On 21/11/2018 17.52, Peter Bergner wrote:
> > On 11/21/18 7:13 AM, Segher Boessenkool wrote:
> >> There is no such switch.  Implementing such a switch would be hard; for
> >> example, the convert-float-to-integer instructions need to store an integer
> >> in a floating point register.
>
> Thanks for the answer. I accept that it would be hard to do such a
> switch, though I don't think I understand that example. Why would gcc
> ever create an int-to-float or float-to-int unless the source code
> actually used float or double?

One of the nastier problems is we need to allow some integer modes in the
floating point registers, for this and similar; so there is no way you can
say "do not put integers in FP regs" and still have a working compiler.

We also need to allow floating point modes in other than FPRs, because
-msoft-float works that way, if nothing else.

> >> Compiling translation units with different needs, with different flags, is
> >> the way to go.  -msoft-float means "do not use the FPRs".
> >
> > I agree with Segher here.  I'll note though that -msoft-float and -mhard-float
> > are different ABIs.  However, if you don't call a function across the soft-float
> > to hard-float barrier that has floating point arguments or floating point
> > return value, you should be fine.
>
> We may have to do it that way, then. But I would hope to have some help
> from the compiler to detect ABI violations, or generation of soft-float
> code. We could build everything with -msoft-float, and all such code
> should be forbidden from using float/double/long double in any way -
> calling functions taking those, defining variables, casting to/from, ...
> either via a new warning, or a hypothetical '-mno-float' [which I see
> actually exists for MIPS]. Then we could selectively turn on
> -mhard-float for the few TUs that actually need that.

For us, hard float is the normal case: PowerPC requires it (and always
has, but some embedded things do not have it, sigh).

Detecting problems should be easy...  Whenever your code tries to access
the floating point registers while you don't have access to them (which
is a flag per context), you get an exception (an interrupt).  So as long
as you keep MSR[FP] turned off for the tasks that should not touch FP
registers, you should be fine.


Segher